何用Java8 Stream API進行數據抽取與收集

上一篇中咱們經過一個實例看到了Java8 Stream API 相較於傳統的的Java 集合操做的簡潔與優點,本篇咱們依然藉助於一個實際的例子來看看Java8 Stream API 如何抽取及收集數據。
備註:上一篇內容:如何用Java8 Stream API找到心儀的女友html

## 目標&背景
咱們以「處理訂單數據」爲例,假設咱們的應用是一個分佈式應用,有"訂單應用","物流應用","商品應用」等都是獨立的服務。本次咱們的目的須要展現訂單列表完整數據:java

  • 1.查詢訂單列表。
  • 2.批量查詢物流信息。
  • 3.將物流信息填充到訂單主信息中。

假設咱們定義了一個訂單類,具備幾個關鍵的屬性:訂單號,狀態,訂單價,快遞信息。以下所示:express

class Order{
    String orderSeq;
    String status;
    double totalPrice;
    String expressInfo;
    // 省略get,set及hashCode等方法
}

咱們定義了一個快遞信息類,幾個關鍵的屬性:訂單號,物流公司,物流單號,物流狀態。以下所示:網絡

class ExpressInfo{
    String orderSeq;
    String expressName;
    String expressNo;
    String createTime;
    String statusInfo;
    // 省略get,set及hashCode等方法
}

Java7 實現

獲取訂單列表 & 抽取訂單號

List<Order> orderList = getOrderList();
    // 抽取 訂單號
    List<String> orderSeqList = new ArrayList<>();
    for (Order order : orderList) {
        orderSeqList.add(order.getOrderSeq());
    }

這裏咱們獲取了訂單列表orderList,此時expressInfo裏邊是沒有數據的。這裏抽取單號依然是Java傳統的寫法。分佈式

批量查詢快遞信息 & 組裝 訂單-快遞信息 map

因爲咱們是經過調用遠程服務來獲取快遞信息,爲了減小網絡通訊次數,咱們採起批量查詢的方式。這也是爲何,上一步中咱們要抽取訂單號
下面咱們來獲取快遞信息code

// 調用遠程服務,
List<ExpressInfo> expressInfos = RpcGetExpressInfoBatch(orderSeqList);
// 組裝 訂單-快遞 關係map
Map<String,String> orderExpressMap = new HashMap<>();
for(ExpressInfo e: expressInfos){
    orderExpressMap.put(e.getOrderSeq(),e.getStatusInfo());
}

這裏組裝map,也依然是Java7經常使用的寫法。htm

組合數據,將快遞信息填充進訂單

for(Order order:orderList){
    String expressInfo = orderExpressMap.get(order.getOrderSeq());
    order.setExpressInfo(expressInfo);
}

至此,咱們使用Java7 的寫法,完成了開篇設定的目標。下面咱們看Java8的寫法對象

Java8 實現

獲取訂單列表 & 抽取訂單號

// 獲取列表
List<Order> orderList = getOrderList();
// 抽取單號
List<String> orderSeqs = orderList.stream()
        .map(Order::getOrderSeq)
        .collect(Collectors.toList());

這裏咱們使用了stream.map,在map()中,咱們的寫法是Order::getOrderSeq表示調用Order對象的getOrderSeq()方法來抽取訂單號。
這裏的::叫「方法應用」,是Java8中的新寫法。
map()後面緊跟的是collect收集器,他將抽取的數據toList(),因而咱們獲得了最終的List blog

批量查詢快遞信息 & 組裝 訂單-快遞信息 map

下面咱們仍然是經過遠程調用來獲取快遞信息,而後使用Java8的語法創建一個 訂單-快遞 關聯信息的map。get

List<ExpressInfo> expressInfos = RpcGetExpressInfoBatch(orderSeqList);
Map<String,String> orderExpressMap =expressInfos.stream()
        .collect(Collectors.toMap(ExpressInfo::getOrderSeq,ExpressInfo::getStatusInfo));

這裏代碼比Java7的要少吧,且一目瞭然,這裏用strean().collect來收集數據,收集成什麼形式呢?看名知意,Collectors.toMap收集成Map,收集什麼數據呢?toMap()中,寫了ExpressInfo::getOrderSeqExpressInfo::getStatusInfo,即:抽取orderSeq做爲key,statusInfo做爲value。

至此,訂單數據,訂單-物流關係數據map都獲得了,下面咱們來組合數據。

組合數據,將快遞信息填充進訂單

通過上面囉嗦的兩步,咱們獲得了符合咱們要求的數據,如今咱們須要根據顏值高低進行排名,代碼以下:

orderList.stream().forEach(o -> o.setExpressInfo(orderExpressMap.get(o.getOrderSeq())));

你沒看錯,就只有這麼一行。

總結

本節,咱們使用Java8 Stream API,完成了數據的抽取和收集,使用了map(),和collect()來完成數據的抽取和收集,並瞭解了兩種收取方式toListtoMap。因此,之後若是有人問你"Java8 stream 如何獲取對象的某個屬性list啊?",「java8 stream 如何獲取指定數據組裝成map啊?」,你就能夠把本文中的方法告訴他了。

除此以外,Java8 Streap API 還有分組 等功能,後面再說。你也能夠關注個人公衆號,第一時間收到推送。

alt 逃離沙漠公衆號

相關文章
相關標籤/搜索