從 Java 流收集連續的對
1. 概述
在 Java Streams 中,有效地處理和轉換資料對於有效的程式設計至關重要。處理連續元素的兩種強大技術是使用SimpleEntry進行直接配對和用於更動態場景的狀態轉換。
在本教程中,我們將探索如何利用SimpleEntry創建相鄰元素對,並了解有狀態轉換如何提供靈活的方法來管理和處理資料流。
讓我們深入了解這些方法如何增強我們的 Java Stream 操作。
2. 問題陳述
給定一個元素流,我們想要建立一個對列表,其中每個對都由流中的連續元素組成。例如,給定一個整數流[1, 2, 3, 4, 5] ,我們想要收集對[(1, 2), (2, 3), (3, 4), (4, 5)] 。
讓我們看看如何找到解決方案。
3. 解決方法
為了從 Java 流中收集連續的對,我們可以根據任務的特定要求和約束使用各種方法。
讓我們看看實現這一目標的兩種常見方法。
3.1.將對收集到List<SimpleEntry>
此方法首先將Stream中的所有元素收集到List中。這允許透過索引存取元素,這是配對所必需的。
我們看一下實作:
public static <T> List<SimpleEntry<T, T>> collectSuccessivePairs(Stream<T> stream) {
List<T> list = stream.collect(Collectors.toList());
return IntStream.range(0, list.size() - 1)
.mapToObj(i -> new SimpleEntry<>(list.get(i), list.get(i + 1))).collect(Collectors.toList());
}
收集所有元素後,我們建立一個索引從0到list.size() – 2的IntStream 。這是因為最後一個元素沒有可配對的連續元素。值得注意的是, IntStream.range(0, list.size() – 1)產生從0到但不包含list.size() – 1索引。
然後,我們將每個索引i對應到包含索引i處的元素和index i + 1處的元素的SimpleEntry 。
最後,我們將這些SimpleEntry物件收集到一個List中。
因此,繼續討論時間複雜度,將流收集到列表的時間複雜度為O(n),使用IntStream.range()配對元素的時間複雜度為O(n).所以,總體時間複雜度為O(n) 。此外,收集的元素列表需要O(n)空間,對列表也需要O(n)空間。所以,總體空間複雜度為O(n) 。
3.2.將對收集到List<List<T>>
List<List<T>>方法提供了一種直接的方法來將流中的連續元素對收集到嵌套列表中。
我們先看一下實作:
public static <T> Stream<List<T>> pairwise(Stream<T> stream) {
List<T> list = stream.collect(Collectors.toList());
List<List<T>> pairs = new ArrayList<>();
for (int i = 0; i < list.size() - 1; i++) {
pairs.add(Arrays.asList(list.get(i), list.get(i + 1)));
}
return pairs.stream();
}
方法pairwise()接受元素Stream並以List形式傳回連續元素對的Stream 。
首先,我們將輸入流中的元素收集到清單中。這允許透過索引隨機存取元素:
然後我們初始化空對來儲存連續的對並循環列表。
- 循環遍歷列表,在倒數第二個元素處停止
- 對於每個元素
list.get(i),它都會與下一個元素list.get(i + 1)建立一對 - 該對已添加到對列表中
最後,該方法將對pairs轉換回流並返回它。
現在,我們來討論時間和空間複雜度。首先,我們將流收集到時間複雜度為 O(n) 的清單中,並以時間複雜度為O(n).的O(n)將元素配對。 So ,整體時間複雜度為O(n).並且,收集的元素列表需要O(n)空間,對列表也需要O(n)空間。所以整體空間複雜度為O(n) 。
4. 結論
在本文中,我們了解到SimpleEntry和有狀態轉換為處理 Java Streams 中的連續對提供了有價值的方法。 SimpleEntry提供了一種乾淨簡潔的方式來建立和管理相鄰元素對,而有狀態轉換則在更複雜的資料處理場景中提供了靈活性和強大功能。透過理解和應用這些技術,我們可以優化流程操作並更有效、更清晰地處理資料。
與往常一樣,所有這些範例的原始程式碼都可以在 GitHub 上取得。