天天看點

Java 8新特性:Stream API Stream API

由David發表在天碼營

Stream API

Stream API是Java8類庫的核心,它能夠應用在一組元素上一次執行的操作序列。

Stream操作分為中間操作或者最終操作兩種,最終操作傳回一特定類型的計算結果,而中間操作傳回Stream本身,這樣你我們就可以将多個操作串起來。

使用Stream的時候需要指定一個資料源,它包括List, Set等集合類。

Filter操作

Stream接口支援很多操作,Filter操作就是最常用的操作之一。在工程中,我們經常需要對一個集合進行過濾。以之前的排序資料為例:

List<SomeObject> words = new ArrayList<>();
words.add(new SomeObject("test5"));
words.add(new SomeObject("some0"));
words.add(new SomeObject("another3"));
words.add(new SomeObject("test1"));
words.add(new SomeObject("some9"));
words.add(new SomeObject("another2"));
           

我們需要過濾掉test的資料:

words.stream().filter((SomeObject someObject) -> !someObject.getSomething().startsWith("test")).forEach(System.out::println);
           

我們使用stream API中的filter函數,它使用了Predicate接口,它的抽象方法傳回值是boolean。filter函數根據它的傳回值判斷該元素是否被過濾掉。forEach方法表示将每個過濾後的每個元素依次執行指定操作。forEach方法使用的是Consumer接口,它的抽象方法表示在單個參數上執行的參數。

Sort操作

Stream同樣支援排序,我們可以指定Comparator函數式接口來讓其按照自定義的方式進行排序:

final int plus = ;
words.stream().sorted((o1, o2) -> (o1.getSomething() + plus).compareTo(o2.getSomething())).forEach(System.out::println);
           

簡單的一句話後排序就完成了,我們可以在之後進行後續操作或疊代輸出。這個操作并不會影響原始資料,而是生成一個新的流供我們使用。

比對

Stream支援多種比對政策,這個操作會傳回boolean告知我們比對結果。

// 測試是否含有字首為test的元素
words.stream().anyMatch((s)->s.getSomething().startsWith("test"));
// 測試是否每個元素字首均為test
words.stream().allMatch((s)->s.getSomething().startsWith("test"));
// 測試是否沒有字尾為的元素
words.stream().noneMatch((s)->s.getSomething().endsWith("1"));
           

映射

中間操作map會将元素根據指定的Function接口來依次将元素轉成另外的對象,下面的示例展示了将字元串轉換為大寫字元串。你也可以通過map來講對象轉換成其他類型,map傳回的Stream類型是根據你map傳遞進去的函數的傳回值決定的。比如我們需要将SomeObject數組的每個元素的something字段都變為大下颚。

words.stream().map(s -> s.getSomething().toUpperCase()).forEach(System.out::println);
           

計數和Reduce

除了按次序輸出,我們也可以使用其他的最終操作。

計數是其中一個常見的操作,我們經常需要統計篩選出元素的個數,通過流接口,我們可以很輕松的完成:

words.stream().filter((SomeObject someObject) -> !someObject.getSomething().startsWith("test")).count();
           

Reduce也是一個很有意思的操作,它允許通過指定的函數來講stream中的多個元素合并為一個元素,結果是通過Optional接口表示,

words.stream().filter((SomeObject someObject) -> !someObject.getSomething().startsWith("test")).reduce((o1, o2)->new SomeObject(o1.getSomething().concat(o2.getSomething())));
           

并行Stream

預設情況下Stream是在一個線程執行的。為了提高性能,我們也可以使用并行Stream。比如之前的filter操作,我們隻要将其調用的

stream

方法改為

parallelStream

即可:

words.parallelStream().filter((SomeObject someObject) -> !someObject.getSomething().startsWith("test")).reduce(
           
Java 8新特性:Stream API Stream API