Spajanje tokova u Javi

1. Pregled

U ovom kratkom članku objašnjavamo različite načine spajanja Jave Potoci - što nije vrlo intuitivna operacija.

2. Korištenje obične Jave

JDK 8 Stream klasa ima neke korisne statičke korisne metode. Pogledajmo pobliže concat () metoda.

2.1. Spajanje dva Potoci

Najjednostavniji način kombiniranja 2 Streams je koristiti statički Stream.concat () metoda:

@Test public void whenMergingStreams_thenResultStreamContainsElementsFromBoth () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Tok rezultira Stream = Stream.concat (stream1, stream2); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6), resultStream.collect (Collectors.toList ())); } 

2.2. Spajanje višestrukih Streams

Kada trebamo spojiti više od 2 Potoci, stvari postaju malo složenije. Jedna je mogućnost spojiti prva dva toka, zatim spojiti rezultat sa sljedećim i tako dalje.

Sljedeći isječak koda to pokazuje na djelu:

@Test javna praznina given3Streams_whenMerged_thenResultStreamContainsAllElements () {Stream stream1 = Stream.of (1, 3, 5); Stream stream2 = Stream.of (2, 4, 6); Stream stream3 = Stream.of (18, 15, 36); Tok rezultira Stream = Stream.concat (Stream.concat (stream1, stream2), stream3); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36), resultStream.collect (Collectors.toList ())); } 

Kao što vidimo, ovaj pristup postaje neizvediv za više tokova. Naravno, možemo stvoriti srednje varijable ili pomoćne metode kako bismo je učinili čitljivijom, ali ovdje je bolja opcija:

@Test javna praznina 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); Tok rezultira Stream = Stream.of (stream1, stream2, stream3, stream4) .flatMap (i -> i); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resultStream.collect (Collectors.toList ())); } 

Što se ovdje događa:

  • Prvo stvaramo novu Stream koji sadrži 4 Potoci, što rezultira a Stream
  • Onda mi flatMap () ovo u Stream pomoću funkcije identiteta

3. Korištenje StreamEx-a

StreamEx je Java biblioteka otvorenog koda koja proširuje mogućnosti Java 8 Streamova. Koristi StreamEx klase kao poboljšanje JDK-a Stream sučelje.

3.1. Spajanje Streams

Biblioteka StreamEx omogućuje spajanje tokova pomoću dodati() metoda instance:

@Test javna praznina 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); Tok rezultira Stream = StreamEx.of (stream1) .append (stream2) .append (stream3) .append (stream4); assertEquals (Arrays.asList (1, 3, 5, 2, 4, 6, 18, 15, 36, 99), resultStream.collect (Collectors.toList ())); } 

Budući da je to metoda instance, možemo je lako povezati i dodati više tokova.

Imajte na umu da bismo mogli stvoriti i Popis izvan toka pomoću izlistati() ako upišemo rezultirajući Stream promjenjiva na StreamEx tip.

3.2. Spajanje tokova pomoću prepend ()

StreamEx također sadrži metodu koja dodaje elemente prije poziva prepend ():

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

4. Koristeći Jooλ

jOOλ je JDK 8 kompatibilna knjižnica koja pruža korisna proširenja za JDK. Ovdje se naziva najvažnija apstrakcija potoka Sljedeće. Imajte na umu da je ovo sekvencijalni i poredani tok, pa pozivanje paralelno() neće imati učinka.

4.1. Spajanje tokova

Baš kao i StreamEx knjižnica, i jOOλ ima dodati() metoda:

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

Također, tu je i pogodnost izlistati() metodu ako upišemo rezultirajućiSljedeća varijabla na jOOλ Sljedeće tip.

4.2. Spajanje tokova sa prepend ()

Očekivano, od dodati() metoda postoji, postoji i prepend () metoda u jOOλ:

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

5. Zaključak

Vidjeli smo da je spajanje tokova relativno jednostavno pomoću JDK 8. Kada moramo napraviti puno spajanja, možda bi bilo korisno koristiti biblioteku StreamEx ili jOOλ radi čitljivosti.

Izvorni kod možete pronaći na GitHubu.