Java 8流簡介

1.概述

在本文中,我們將快速瀏覽Java 8添加的主要新功能之一-流。

我們將解釋流的含義,並通過簡單的示例展示流的創建和基本操作。

2.流API

Java 8的主要新功能之一是引入了流功能java.util.stream ,該功能包含用於處理元素序列的類。

中心的API類是[Stream<T>](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html) .下一節將演示如何使用現有的數據提供者源創建流。

2.1。流創建

可以使用stream()of()方法從不同的元素源(例如集合或數組)創建stream()

String[] arr = new String[]{"a", "b", "c"};

 Stream<String> stream = Arrays.stream(arr);

 stream = Stream.of("a", "b", "c");

stream()默認方法添加到Collection接口,並允許使用任何集合作為元素源來創建Stream<T> :

Stream<String> stream = list.stream();

2.2。流多線程

Stream API還提供了parallelStream()方法,該方法以並行模式對流的元素運行操作,從而簡化了多線程處理。

下面的代碼允許為流的每個元素並行運行doWork()方法:

list.parallelStream().forEach(element -> doWork(element));

在以下部分中,我們將介紹一些基本的Stream API操作。

3.流操作

在流上可以執行許多有用的操作。

它們分為中間操作(返回Stream<T> )和終端操作(返回確定類型的結果)。中間操作允許鏈接。

還值得注意的是,對流的操作不會更改源。

這是一個簡單的例子:

long count = list.stream().distinct().count();

因此, distinct()方法表示一個中間操作,該操作創建了先前流的唯一元素的新流。 count()方法是一個終端操作,它返回流的大小。

3.1。反復進行

流API有助於替代forfor-each ,並while循環。它允許專注於操作的邏輯,但不能專注於元素序列的迭代。例如:

for (String string : list) {

 if (string.contains("a")) {

 return true;

 }

 }

只需一行Java 8代碼即可更改此代碼:

boolean isExist = list.stream().anyMatch(element -> element.contains("a"));

3.2。篩選

filter()方法允許我們選擇滿足謂詞的元素流。

例如,考慮以下列表:

ArrayList<String> list = new ArrayList<>();

 list.add("One");

 list.add("OneAndOnly");

 list.add("Derek");

 list.add("Change");

 list.add("factory");

 list.add("justBefore");

 list.add("Italy");

 list.add("Italy");

 list.add("Thursday");

 list.add("");

 list.add("");

以下代碼創建List<String>Stream<String> ,查找此流中包含char “d”所有元素,並創建一個僅包含過濾後的元素的新流:

Stream<String> stream = list.stream().filter(element -> element.contains("d"));

3.3。Mapping

為了通過對Stream元素應用特殊功能來轉換它們並將這些新元素收集到Stream ,我們可以使用map()方法:

List<String> uris = new ArrayList<>();

 uris.add("C:\\My.txt");

 Stream<Path> stream = uris.stream().map(uri -> Paths.get(uri));

因此,以上代碼通過將特定的lambda表達式應用於初始Stream每個元素,將Stream<String>轉換為Stream<Path>

如果您有一個流,其中每個元素都包含其自己的元素序列,並且想要創建這些內部元素的流,則應使用flatMap()方法:

List<Detail> details = new ArrayList<>();

 details.add(new Detail());

 Stream<String> stream

 = details.stream().flatMap(detail -> detail.getParts().stream());

在這個例子中,我們有一個類型為Detail的元素列表。 Detail類包含一個字段PARTS ,它是一個List<String> 。借助flatMap()方法,將提取字段PARTS每個元素並將其添加到新的結果流中。之後,初始Stream<Detail>將丟失.

3.4。匹配

Stream API提供了一組方便的工具來根據某些謂詞驗證序列的元素。為此,可以使用以下方法之一: anyMatch(), allMatch(), noneMatch().他們的名字是不言自明的。這些是返回boolean終端操作:

boolean isValid = list.stream().anyMatch(element -> element.contains("h")); // true

 boolean isValidOne = list.stream().allMatch(element -> element.contains("h")); // false

 boolean isValidTwo = list.stream().noneMatch(element -> element.contains("h")); // false

對於空流,具有任何給定謂詞的allMatch()方法將返回true

Stream.empty().allMatch(Objects::nonNull); // true

這是一個明智的默認值,因為我們找不到任何不滿足謂詞的元素。

同樣, anyMatch()方法對於空流始終返回false

Stream.empty().anyMatch(Objects::nonNull); // false

同樣,這是合理的,因為我們找不到滿足此條件的元素。

3.5。減少

Stream API借助Stream類型的reduce()方法,可以根據指定的函數將元素序列減少為某個值。此方法有兩個參數:第一個-起始值,第二個-累加器功能。

假設您有一個List<Integer>並且希望所有這些元素和一些初始Integer的總和(在本例中為23)。因此,您可以運行以下代碼,結果將為26(23 +1 + 1 +1)。

List<Integer> integers = Arrays.asList(1, 1, 1);

 Integer reduced = integers.stream().reduce(23, (a, b) -> a + b);

3.6。收集中

還可以通過Stream.類型的collect()方法來提供減少量Stream.在將流轉換為CollectionMap並以單個字符串形式表示流的情況下,此操作非常方便.有一個實用程序類Collectors ,可以為幾乎所有典型的收集操作提供解決方案。對於一些並非微不足道的任務,可以創建自定義Collector

List<String> resultList

 = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList());

此代碼使用終端的collect()操作將Stream<String>簡化為List<String>.

4。結論

在本文中,我們簡要介紹了Java流-絕對是Java 8最有趣的功能之一。

有許多使用Streams的更高級的示例。撰寫本文的目的只是為了快速,實用地介紹您可以使用該功能開始做些什麼,並以此作為探索和進一步學習的起點。

本文隨附的源代碼可在GitHub上獲得