Penggabungan Aliran di Java

1. Gambaran keseluruhan

Dalam artikel ringkas ini, kami menerangkan pelbagai cara menggabungkan Java Stream - yang bukan merupakan operasi yang sangat intuitif.

2. Menggunakan Java Plain

Kelas JDK 8 Stream mempunyai beberapa kaedah utiliti statik yang berguna. Mari kita perhatikan lebih dekat kaedah concat () .

2.1. Menggabungkan Dua Aliran

Cara termudah untuk menggabungkan 2 Stream s adalah dengan menggunakan kaedah Stream.concat () statik :

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

2.2. Penggabungan Multiple Stream s

Apabila kita perlu menggabungkan lebih daripada 2 Aliran, keadaan menjadi lebih rumit. Satu kemungkinan adalah menggabungkan dua aliran pertama, kemudian menggabungkan hasilnya dengan yang berikutnya dan seterusnya.

Coretan kod seterusnya menunjukkan tindakan ini:

@Test public void 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 resultingStream = Stream.concat( Stream.concat(stream1, stream2), stream3); assertEquals( Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36), resultingStream.collect(Collectors.toList())); } 

Seperti yang kita lihat, pendekatan ini menjadi tidak dapat dilaksanakan untuk lebih banyak aliran. Sudah tentu, kita boleh membuat pemboleh ubah antara atau kaedah pembantu untuk menjadikannya lebih mudah dibaca, tetapi berikut adalah pilihan yang lebih baik:

@Test public void 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 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())); } 

Apa yang berlaku di sini ialah:

  • Kami pertama kali membuat Aliran baru yang mengandungi 4 Aliran, yang menghasilkan Aliran
  • Kemudian kami flatMap () ini ke dalam Stream menggunakan fungsi identiti

3. Menggunakan StreamEx

StreamEx adalah pustaka Java sumber terbuka yang memperluas kemungkinan Java 8 Stream. Ia menggunakan kelas StreamEx sebagai penambahbaikan pada antara muka Stream JDK .

3.1. Penggabungan Aliran s

Perpustakaan StreamEx membolehkan kita menggabungkan aliran menggunakan kaedah contoh append () :

@Test public void 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 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())); } 

Oleh kerana ia adalah kaedah contoh, kita dapat dengan mudah mengaitkannya dan menambahkan beberapa aliran.

Perhatikan bahawa kita juga dapat membuat Daftar di luar aliran dengan menggunakan toList () jika kita mengetik pemboleh ubahStream yang dihasilkan ke jenis StreamEx .

3.2. Menggabungkan Aliran Menggunakan prepend ()

StreamEx juga mengandungi kaedah yang menambahkan elemen sebelum satu sama lain disebut prepend () :

@Test public void given3Streams_whenPrepended_thenResultStreamContainsAllElements() { Stream stream1 = Stream.of("foo", "bar"); Stream openingBracketStream = Stream.of("["); Stream closingBracketStream = Stream.of("]"); Stream resultingStream = StreamEx.of(stream1) .append(closingBracketStream) .prepend(openingBracketStream); assertEquals( Arrays.asList("[", "foo", "bar", "]"), resultingStream.collect(Collectors.toList())); } 

4. Menggunakan Jooλ

jOOλ adalah perpustakaan yang serasi dengan JDK 8 yang memberikan sambungan berguna kepada JDK. Pengaliran aliran yang paling penting di sini dipanggil Seq . Perhatikan bahawa ini adalah aliran berurutan dan teratur, jadi panggilan selari () tidak akan memberi kesan.

4.1. Penggabungan Aliran

Sama seperti perpustakaan StreamEx, jOOλ mempunyai kaedah append () :

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

Juga, ada kaedah kemudahan untuk Daftar () jika kita menaip pemboleh ubahSeq yang dihasilkan ke jenis JOOλ Seq .

4.2. Penggabungan Aliran Dengan Pra (

Seperti yang dijangkakan, kerana kaedah append () ada, ada juga kaedah prepend () di jOOλ:

@Test public void given3Streams_whenPrepending_thenResultStreamContainsAllElements() { Stream seq = Stream.of("foo", "bar"); Stream openingBracketSeq = Stream.of("["); Stream closingBracketSeq = Stream.of("]"); Stream resultingStream = Seq.ofType(seq, String.class) .append(closingBracketSeq) .prepend(openingBracketSeq); Assert.assertEquals( Arrays.asList("[", "foo", "bar", "]"), resultingStream.collect(Collectors.toList())); } 

5. Kesimpulan

Kami melihat penggabungan aliran relatif mudah menggunakan JDK 8. Apabila kita perlu melakukan penggabungan banyak, mungkin bermanfaat untuk menggunakan perpustakaan StreamEx atau jOOλ demi kesediaan membaca.

Anda boleh mendapatkan kod sumber di GitHub.