合併Java流

1.概述

在這篇快速文章中,我們解釋了合併Java Streams不同方法-這不是一個非常直觀的操作。

2.使用純Java

JDK 8 Stream類具有一些有用的靜態實用程序方法。讓我們仔細看一下concat()方法。

2.1。合併兩個Streams

組合2個Stream的最簡單方法是使用靜態Stream.concat()方法:

@Test

 public void whenMergingStreams_thenResultStreamContainsElementsFromBoth() {

 Stream<Integer> stream1 = Stream.of(1, 3, 5);

 Stream<Integer> stream2 = Stream.of(2, 4, 6);



 Stream<Integer> resultingStream = Stream.concat(stream1, stream2);



 assertEquals(

 Arrays.asList(1, 3, 5, 2, 4, 6),

 resultingStream.collect(Collectors.toList()));

 }

2.2。合併多個Stream

當我們需要合併兩個以上的Streams,事情會變得更加複雜。一種可能是連接前兩個流,然後將結果與下一個流連接,依此類推。

下一個代碼片段顯示了這一操作:

@Test

 public void given3Streams_whenMerged_thenResultStreamContainsAllElements() {

 Stream<Integer> stream1 = Stream.of(1, 3, 5);

 Stream<Integer> stream2 = Stream.of(2, 4, 6);

 Stream<Integer> stream3 = Stream.of(18, 15, 36);



 Stream<Integer> resultingStream = Stream.concat(

 Stream.concat(stream1, stream2), stream3);



 assertEquals(

 Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36),

 resultingStream.collect(Collectors.toList()));

 }

如我們所見,這種方法對於更多的流來說是不可行的。當然,我們可以創建中間變量或輔助方法以使其更具可讀性,但這是一個更好的選擇:

@Test

 public void given4Streams_whenMerged_thenResultStreamContainsAllElements() {

 Stream<Integer> stream1 = Stream.of(1, 3, 5);

 Stream<Integer> stream2 = Stream.of(2, 4, 6);

 Stream<Integer> stream3 = Stream.of(18, 15, 36);

 Stream<Integer> stream4 = Stream.of(99);



 Stream<Integer> resultingStream = Stream.of(

 stream1, stream2, stream3, stream4)

 .flatMap(i -> i);



 assertEquals(

 Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99),

 resultingStream.collect(Collectors.toList()));

 }

這裡發生的是:

  • 我們首先創建一個包含4個Streams,的新Stream Streams,這將導致Stream<Stream<Integer>>
  • 然後,我們使用identity函數將其flatMap()轉換為Stream<Integer>

3.使用StreamEx

StreamEx是一個開源Java庫,它擴展了Java 8 Streams的可能性。它使用StreamEx類作為對JDK的Stream接口的增強。

3.1。合併Stream

StreamEx庫允許我們使用append()實例方法合併流:

@Test

 public void given4Streams_whenMerged_thenResultStreamContainsAllElements() {

 Stream<Integer> stream1 = Stream.of(1, 3, 5);

 Stream<Integer> stream2 = Stream.of(2, 4, 6);

 Stream<Integer> stream3 = Stream.of(18, 15, 36);

 Stream<Integer> stream4 = Stream.of(99);



 Stream<Integer> resultingStream = StreamEx.of(stream1)

 .append(stream2)

 .append(stream3)

 .append(stream4);



 assertEquals(

 Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99),

 resultingStream.collect(Collectors.toList()));

 }

由於它是一個實例方法,因此我們可以輕鬆地將其鏈接並追加多個流。

需要注意的是,我們還可以創建一個List ,通過使用出流的toList()如果我們鍵入resultingStream變量的StreamEx類型。

3.2。使用prepend()合併流

StreamEx還包含一種在元素之間添加元素的方法,稱為prepend()

@Test

 public void given3Streams_whenPrepended_thenResultStreamContainsAllElements() {

 Stream<String> stream1 = Stream.of("foo", "bar");

 Stream<String> openingBracketStream = Stream.of("[");

 Stream<String> closingBracketStream = Stream.of("]");



 Stream<String> resultingStream = StreamEx.of(stream1)

 .append(closingBracketStream)

 .prepend(openingBracketStream);



 assertEquals(

 Arrays.asList("[", "foo", "bar", "]"),

 resultingStream.collect(Collectors.toList()));

 }

4.使用Jooλ

jOOλ是JDK 8兼容的庫,它提供了對JDK的有用擴展。這裡最重要的流抽象稱為Seq 。請注意,這是一個順序且有序的流,因此調用parallel()將無效。

4.1。合併流

就像StreamEx庫一樣,jOOλ具有append()方法:

@Test

 public void given2Streams_whenMerged_thenResultStreamContainsAllElements() {

 Stream<Integer> seq1 = Stream.of(1, 3, 5);

 Stream<Integer> seq2 = Stream.of(2, 4, 6);



 Stream<Integer> resultingSeq = Seq.ofType(seq1, Integer.class)

 .append(seq2);



 assertEquals(

 Arrays.asList(1, 3, 5, 2, 4, 6),

 resultingSeq.collect(Collectors.toList()));

 }

另外,如果我們將resultingSeq變量Seq鍵入為jOOλSeq類型,則toList()方法也很方便。

4.2。使用prepend()合併流

不出所料,由於存在append()方法,因此jOOλ中還有一個prepend()方法:

@Test

 public void given3Streams_whenPrepending_thenResultStreamContainsAllElements() {

 Stream<String> seq = Stream.of("foo", "bar");

 Stream<String> openingBracketSeq = Stream.of("[");

 Stream<String> closingBracketSeq = Stream.of("]");



 Stream<String> resultingStream = Seq.ofType(seq, String.class)

 .append(closingBracketSeq)

 .prepend(openingBracketSeq);



 Assert.assertEquals(

 Arrays.asList("[", "foo", "bar", "]"),

 resultingStream.collect(Collectors.toList()));

 }

5.結論

我們看到使用JDK 8合併流是相對簡單的。當需要進行大量合併時,出於可讀性考慮,使用StreamEx或jOOλ庫可能會有所幫助。

您可以在GitHub上找到源代碼。