1. 程式人生 > >java stream操作

java stream操作

Java 8 中的 Streams API 詳解

Streams 的背景,以及 Java 8 中的使用詳解

陳 爭雲, 佔 宇劍, 和 司 磊
2014 年 9 月 11 日釋出

WeiboGoogle+

Comments   16

為什麼需要 Stream

Stream 作為 Java 8 的一大亮點,它與 java.io 包裡的 InputStream 和 OutputStream 是完全不同的概念。它也不同於 StAX 對 XML 解析的 Stream,也不是 Amazon Kinesis 對大資料實時處理的 Stream。Java 8 中的 Stream 是對集合(Collection)物件功能的增強,它專注於對集合物件進行各種非常便利、高效的聚合操作(aggregate operation),或者大批量資料操作 (bulk data operation)。Stream API 藉助於同樣新出現的 Lambda 表示式,極大的提高程式設計效率和程式可讀性。同時它提供序列和並行兩種模式進行匯聚操作,併發模式能夠充分利用多核處理器的優勢,使用 fork/join 並行方式來拆分任務和加速處理過程。通常編寫並行程式碼很難而且容易出錯, 但使用 Stream API 無需編寫一行多執行緒的程式碼,就可以很方便地寫出高效能的併發程式。所以說,Java 8 中首次出現的 java.util.stream 是一個函式式語言+多核時代綜合影響的產物。

什麼是聚合操作

在傳統的 J2EE 應用中,Java 程式碼經常不得不依賴於關係型資料庫的聚合操作來完成諸如:

  • 客戶每月平均消費金額
  • 最昂貴的在售商品
  • 本週完成的有效訂單(排除了無效的)
  • 取十個資料樣本作為首頁推薦

這類的操作。

但在當今這個資料大爆炸的時代,在資料來源多樣化、資料海量化的今天,很多時候不得不脫離 RDBMS,或者以底層返回的資料為基礎進行更上層的資料統計。而 Java 的集合 API 中,僅僅有極少量的輔助型方法,更多的時候是程式設計師需要用 Iterator 來遍歷集合,完成相關的聚合應用邏輯。這是一種遠不夠高效、笨拙的方法。在 Java 7 中,如果要發現 type 為 grocery 的所有交易,然後返回以交易值降序排序好的交易 ID 集合,我們需要這樣寫:

清單 1. Java 7 的排序、取值實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 List< Transaction > groceryTransactions = new Arraylist<>(); for(Transaction t: transactions){   if(t.getType() == Transaction.GROCERY){   groceryTransactions.add(t);   } } Collections.sort(groceryTransactions, new Comparator(){   public int compare(Transaction t1, Transaction t2){   return t2.getValue().compareTo(t1.getValue());   } }); List< Integer > transactionIds = new ArrayList<>(); for(Transaction t: groceryTransactions){   transactionsIds.add(t.getId()); }

而在 Java 8 使用 Stream,程式碼更加簡潔易讀;而且使用併發模式,程式執行速度更快。

清單 2. Java 8 的排序、取值實現
1 2 3 4 5 List< Integer > transactionsIds = transactions.parallelStream().   filter(t -> t.getType() == Transaction.GROCERY).   sorted(comparing(Transaction::getValue).reversed()).   map(Transaction::getId).   collect(toList());

Stream 總覽

什麼是流

Stream 不是集合元素,它