Slå sammen strømmer i Java

1. Oversikt

I denne raske artikkelen forklarer vi forskjellige måter å slå sammen Java på Strømmer - som ikke er en veldig intuitiv operasjon.

2. Bruke vanlig Java

JDK 8 Strøm klasse har noen nyttige statiske verktøymetoder. La oss se nærmere på concat () metode.

2.1. Fusjonerer to Strømmer

Den enkleste måten å kombinere 2 på Strøms er å bruke det statiske Stream.concat () metode:

@Test offentlig ugyldig nårMergingStreams_thenResultStreamContainsElementsFromBoth () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Stream resulterendeStream = Stream.concat (stream1, stream2); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6), resulterendeStream.collect (Collectors.toList ())); } 

2.2. Slå sammen flere Strøms

Når vi trenger å slå sammen mer enn 2 Strømmer, ting blir litt mer komplekse. En mulighet er å sammenkoble de to første strømmene, og deretter sammenkoble resultatet med den neste og så videre.

Neste kodebit viser dette i aksjon:

@Test offentlig ugyldighet gitt3Streams_whenMerged_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Stream stream3 = Stream.of (18, 15, 36); Stream resulterendeStream = Stream.concat (Stream.concat (stream1, stream2), stream3); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36), resulterendeStream.collect (Collectors.toList ())); } 

Som vi kan se, blir denne tilnærmingen umulig for flere strømmer. Selvfølgelig kan vi lage mellomvariabler eller hjelpemetoder for å gjøre det mer lesbart, men her er et bedre alternativ:

@Test offentlig ugyldig given4Streams_whenMerged_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Stream stream3 = Stream.of (18, 15, 36); Stream stream4 = Stream.of (99); Stream resulterendeStream = Stream.of (stream1, stream2, stream3, stream4) .flatMap (i -> i); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resulterendeStream.collect (Collectors.toList ())); } 

Det som skjer her er:

  • Vi oppretter først en ny Strøm inneholder 4 Strømmer, som resulterer i en Strøm
  • Da vi flatMap () dette til en Strøm bruker identitetsfunksjonen

3. Bruke StreamEx

StreamEx er et open source Java-bibliotek som utvider mulighetene for Java 8 Streams. Den bruker StreamEx klasse som en forbedring av JDK-ene Strøm grensesnitt.

3.1. Sammenslåing Strøms

StreamEx-biblioteket lar oss slå sammen strømmer ved hjelp av legg til () eksempel metode:

@Test offentlig ugyldig given4Streams_whenMerged_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Stream stream3 = Stream.of (18, 15, 36); Stream stream4 = Stream.of (99); Stream resulterendeStream = StreamEx.of (stream1) .append (stream2) .append (stream3) .append (stream4); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resulterendeStream.collect (Collectors.toList ())); } 

Siden det er en forekomstmetode, kan vi enkelt kjede den og legge til flere strømmer.

Merk at vi også kan lage en Liste ut av strømmen ved å bruke å liste opp() hvis vi skriver inn resulterendeStream variabel til StreamEx type.

3.2. Flette strømmer ved hjelp av avhengig ()

StreamEx inneholder også en metode som legges til elementer før hverandre avhengig ():

@Test offentlig ugyldig gitt3Streams_whenPrepended_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of ("foo", "bar"); Stream openingBracketStream = Stream.of ("["); Strøm lukkingBracketStream = Stream.of ("]"); Stream resulterendeStream = StreamEx.of (stream1) .append (closedBracketStream) .prepend (openingBracketStream); assertEquals (Arrays.asList ("[", "foo", "bar", "]"), resulterendeStream.collect (Collectors.toList ())); } 

4. Bruke Jooλ

jOOλ er et JDK 8-kompatibelt bibliotek som gir nyttige utvidelser til JDK. Den viktigste stream-abstraksjonen her kalles Sekv. Merk at dette er en sekvensiell og ordnet strøm, så ring parallell() vil ikke ha noen effekt.

4.1. Slå sammen strømmer

Akkurat som StreamEx-biblioteket har jOOλ en legg til () metode:

@Test offentlig ugyldighet gitt2Streams_whenMerged_thenResultStreamContainsAllElements () {Stream seq1 = Stream.of (1, 3, 5); Stream seq2 = Stream.of (2, 4, 6); Stream resultSeq = Seq.ofType (seq1, Integer.class) .append (seq2); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6), resulterendeSeq.collect (Collectors.toList ())); } 

Det er også en bekvemmelighet å liste opp() metoden hvis vi skriver inn resulterende Sekv variabel til jOOλ Sekv type.

4.2. Slå sammen bekker med avhengig ()

Som forventet, siden en legg til () metoden eksisterer, er det også en avhengig () metode i jOOλ:

@Test offentlig ugyldig gitt3Streams_whenPrepending_thenResultStreamContainsAllElements () {Stream seq = Stream.of ("foo", "bar"); Stream openingBracketSeq = Stream.of ("["); Strøm lukkingBracketSeq = Stream.of ("]"); Stream resulterendeStream = Seq.ofType (seq, String.class) .append (closedBracketSeq) .prepend (openingBracketSeq); Assert.assertEquals (Arrays.asList ("[", "foo", "bar", "]"), resulterendeStream.collect (Collectors.toList ())); } 

5. Konklusjon

Vi så at sammenslåing av strømmer er relativt grei med JDK 8. Når vi trenger å gjøre mye sammenslåing, kan det være fordelaktig å bruke StreamEx- eller jOOλ-biblioteket for lesbarhets skyld.

Du kan finne kildekoden på GitHub.