Fletning af streams i Java

1. Oversigt

I denne hurtige artikel forklarer vi forskellige måder at flette Java på Strømme - hvilket ikke er en meget intuitiv operation.

2. Brug af almindelig Java

JDK 8 Strøm klasse har nogle nyttige statiske hjælpemetoder. Lad os se nærmere på concat () metode.

2.1. Fletning af to Strømme

Den enkleste måde at kombinere 2 på Strøms er at bruge 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. Flet flere Strøms

Når vi har brug for at fusionere mere end 2 Strømme, tingene bliver lidt mere komplekse. En mulighed er at sammenkæde de første to strømme, derefter sammenkæde resultatet med den næste osv.

Det næste kodestykke viser dette i aktion:

@Test offentlig ugyldighed given3Streams_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, bliver denne tilgang umulig for flere strømme. Selvfølgelig kan vi oprette mellemvariabler eller hjælpemetoder for at gøre det mere læsbart, men her er en bedre mulighed:

@Test offentligt ugyldigt 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 ())); } 

Hvad der sker her er:

  • Vi opretter først en ny Strøm indeholdende 4 Strømme, hvilket resulterer i en Strøm
  • Så vi flatMap () dette til en Strøm ved hjælp af identitetsfunktionen

3. Brug af StreamEx

StreamEx er et open source Java-bibliotek, der udvider mulighederne for Java 8 Streams. Det bruger StreamEx klasse som en forbedring af JDK'erne Strøm interface.

3.1. Fletning Strøms

StreamEx-biblioteket giver os mulighed for at flette streams ved hjælp af Tilføj() eksempel metode:

@Test offentligt ugyldigt 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 ())); } 

Da det er en instansmetode, kan vi let kæde det og tilføje flere streams.

Bemærk, at vi også kunne oprette en Liste ud af strømmen ved hjælp af toList () hvis vi skriver resulterendeStream variabel til StreamEx type.

3.2. Fletning af strømme ved hjælp af prepend ()

StreamEx indeholder også en metode, der tilføjer elementer før hinanden kaldes prepend ():

@Test offentligt ugyldigt given3Streams_whenPrepended_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of ("foo", "bar"); Stream openingBracketStream = Stream.of ("["); Stream closedBracketStream = Stream.of ("]"); Stream resulterendeStream = StreamEx.of (stream1) .append (closedBracketStream) .prepend (openingBracketStream); assertEquals (Arrays.asList ("[", "foo", "bar", "]"), resulterendeStream.collect (Collectors.toList ())); } 

4. Brug af Jooλ

jOOλ er et JDK 8-kompatibelt bibliotek, der giver nyttige udvidelser til JDK. Den vigtigste stream-abstraktion kaldes her Sekv. Bemærk, at dette er en sekventiel og ordnet stream, så kald parallel() har ingen virkning.

4.1. Fletning af vandløb

Ligesom StreamEx-biblioteket har jOOλ en Tilføj() metode:

@Test offentligt ugyldigt givet2Streams_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 ())); } 

Der er også en bekvemmelighed toList () metode, hvis vi skriver resulterende Sekv variabel til jOOλ Sekv type.

4.2. Fletning af vandløb med prepend ()

Som forventet, siden en Tilføj() metode findes, er der også en prepend () metode i jOOλ:

@Test offentligt ugyldigt given3Streams_whenPrepending_thenResultStreamContainsAllElements () {Stream seq = Stream.of ("foo", "bar"); Stream openingBracketSeq = Stream.of ("["); Stream afslutningBracketSeq = Stream.of ("]"); Stream resulterendeStream = Seq.ofType (seq, String.class) .append (closedBracketSeq) .prepend (openingBracketSeq); Assert.assertEquals (Arrays.asList ("[", "foo", "bar", "]"), resulterendeStream.collect (Collectors.toList ())); } 

5. Konklusion

Vi så, at fletning af streams er relativt ligetil ved hjælp af JDK 8. Når vi har brug for meget fletning, kan det være en fordel at bruge StreamEx- eller jOOλ-biblioteket af hensyn til læsbarheden.

Du kan finde kildekoden over på GitHub.