Java - Gabungkan Pelbagai Koleksi

1. Gambaran keseluruhan

Dalam tutorial ini, kami akan menggambarkan bagaimana menggabungkan beberapa koleksi menjadi satu koleksi logik.

Kami akan meneroka lima pendekatan yang berbeza - dua menggunakan Java 8, satu menggunakan Jambu, satu menggunakan Koleksi Apache Commons, dan satu hanya menggunakan SDK Java 7 standard.

Dalam contoh berikut, mari kita pertimbangkan koleksi berikut:

Collection collectionA = Arrays.asList("S", "T"); Collection collectionB = Arrays.asList("U", "V");

2. Menggunakan Java 8 Stream API

The Stream antara muka dalam Java API menyediakan kaedah berguna yang membuat ia lebih mudah untuk koleksi proses. Mari kita lihat dua kaedahnya - concat () dan flatMap () - yang digunakan untuk menggabungkan koleksi.

Sebaik sahaja anda mendapat Aliran , anda boleh melakukan operasi agregat di atasnya.

2.1. Menggunakan Kaedah concat ()

Kaedah statik CONCAT () menggabungkan dua Streams secara logik dengan membuat malas concatenated Stream di mana elemen adalah semua unsur-unsur yang pertama Stream diikuti oleh semua unsur-unsur kedua Stream .

Dalam contoh di bawah, mari kita menggabungkan collectionA dan collectionB menggunakan CONCAT () kaedah:

Stream combinedStream = Stream.concat( collectionA.stream(), collectionB.stream());

Sekiranya anda perlu menggabungkan lebih daripada dua Aliran , anda boleh menggunakan kaedah concat () sekali lagi dari dalam permintaan asal:

Stream combinedStream = Stream.concat( Stream.concat(collectionA.stream(), collectionB.stream()), collectionC.stream());

Penting untuk diperhatikan bahawa Stream Java 8 tidak dapat digunakan kembali, jadi anda harus mempertimbangkannya ketika menetapkannya ke pemboleh ubah.

2.2. Menggunakan flatMap () Menghubungi

Kaedah flatMap () mengembalikan Aliran setelah menggantikan setiap elemen Aliran ini dengan kandungan Aliran yang dipetakan yang dihasilkan dengan menerapkan fungsi pemetaan yang disediakan untuk setiap elemen.

Contoh di bawah menunjukkan penggabungan koleksi menggunakan kaedah flatMap () . Pada mulanya, anda mendapat Aliran yang elemennya adalah dua koleksi, dan kemudian anda meratakan Aliran sebelum mengumpulkannya ke dalam senarai gabungan:

Stream combinedStream = Stream.of(collectionA, collectionB) .flatMap(Collection::stream); Collection collectionCombined = combinedStream.collect(Collectors.toList());

3. Menggunakan Jambu Batu

Perpustakaan Jambu dari Google menyediakan beberapa kaedah kemudahan untuk beroperasi pada koleksi dan dapat digunakan dengan Java 6 atau lebih baru.

3.1. Menggunakan Iterables.concat () Menghubungi

Kaedah Iterables.concat () adalah salah satu kaedah mudah Jambu yang digunakan untuk menggabungkan koleksi:

Iterable combinedIterables = Iterables.unmodifiableIterable( Iterables.concat(collectionA, collectionA));

The Iterable yang dikembalikan boleh ditukar ke dalam koleksi:

Collection collectionCombined = Lists.newArrayList(combinedIterables);

3.2. Ketergantungan Maven

Tambahkan kebergantungan berikut ke fail pom.xml Maven anda untuk memasukkan perpustakaan Jambu Batu dalam projek anda:

 com.google.guava guava 20.0 

Anda boleh mendapatkan versi terbaru perpustakaan Jambu di repositori Maven Central.

4. Menggunakan Koleksi Apache Commons

Apache Commons Collections adalah satu lagi perpustakaan utiliti yang membantu bekerja dengan pelbagai koleksi. Perpustakaan menyediakan dua kaedah utiliti yang boleh digunakan untuk menggabungkan koleksi. Di bahagian ini, mari kita fahami bagaimana kaedah ini berfungsi.

4.1. Menggunakan IterableUtils.chainedIterable () Menghubungi

The IterableUtils kelas menyediakan kaedah utiliti dan juruhias untuk Iterable keadaan. Ini menyediakan kaedah chainedIterable () , yang dapat digunakan untuk menggabungkan beberapa Iterable menjadi satu.

Iterable combinedIterables = IterableUtils.chainedIterable( collectionA, collectionB);

4.2. Menggunakan Kaedah CollectionUtils.union ()

Kaedah utiliti dan penghias untuk contoh Koleksi disediakan oleh kelas CollectionUtils . Kaedah penyatuan () dari kelas ini mengembalikan Koleksi yang mengandungi penyatuan contoh Iterable yang diberikan .

Iterable combinedIterables = CollectionUtils.union( collectionA, collectionB);

Dalam kes kaedah penyatuan () , kardinaliti setiap elemen dalam koleksi yang dikembalikan akan sama dengan maksimum kardinaliti elemen tersebut dalam dua Iterables yang diberikan . Ini bermaksud bahawa koleksi gabungan hanya terdiri daripada unsur-unsur pada koleksi pertama dan unsur-unsur dalam koleksi kedua yang tidak ada pada koleksi pertama.

4.3. Ketergantungan Maven

Tambahkan kebergantungan berikut ke fail Maven pom.xml anda untuk memasukkan perpustakaan Apache Commons Collections dalam projek anda:

 org.apache.commons commons-collections4 4.1 

Anda boleh mendapatkan versi terbaru perpustakaan Apache Commons di repositori Maven Central.

5. Menggunakan Java 7

Sekiranya anda masih menggunakan Java 7 dan ingin mengelakkan perpustakaan pihak ketiga seperti Jambu, anda boleh menggunakan kaedah addAll () untuk menggabungkan elemen dari pelbagai koleksi, atau anda boleh menulis kaedah utiliti anda sendiri untuk menggabungkan Iterables .

5.1. Menggunakan addAll () Menghubungi

Sudah tentu penyelesaian termudah untuk menggabungkan koleksi adalah menggunakan kaedah addAll () , seperti dalam contoh Senarai berikut , namun perlu diingat bahawa kaedah ini membuat koleksi baru dengan rujukan tambahan pada objek yang sama yang terdapat dalam dua koleksi pertama:

List listC = new ArrayList(); listC.addAll(listA); listC.addAll(listB);

5.2. Menulis Custom CONCAT () Menghubungi

Contoh di bawah menentukan kaedah concat () yang menerima dua Iterables dan mengembalikan objek Iterable yang digabungkan :

public static  Iterable concat( Iterable i1, Iterable i2) { return new Iterable() { public Iterator iterator() { return new Iterator() { Iterator listIterator = i1.iterator(); Boolean checkedHasNext; E nextValue; private boolean startTheSecond; void theNext() { if (listIterator.hasNext()) { checkedHasNext = true; nextValue = listIterator.next(); } else if (startTheSecond) checkedHasNext = false; else { startTheSecond = true; listIterator = i2.iterator(); theNext(); } } public boolean hasNext() { if (checkedHasNext == null) theNext(); return checkedHasNext; } public E next() { if (!hasNext()) throw new NoSuchElementException(); checkedHasNext = null; return nextValue; } public void remove() { listIterator.remove(); } }; } }; }

Kaedah concat () dapat dipanggil dengan menyampaikan dua koleksi sebagai argumennya:

Iterable combinedIterables = concat(collectionA, collectionB); Collection collectionCombined = makeListFromIterable(combinedIterables);

Sekiranya anda memerlukan Iterable tersedia sebagai Senarai , anda juga boleh menggunakan kaedah makeListFromIterable () yang membuat Senarai menggunakan anggota Iterable :

public static  List makeListFromIterable(Iterable iter) { List list = new ArrayList(); for (E item : iter) { list.add(item); } return list; }

6. Kesimpulannya

Artikel tersebut membincangkan beberapa cara untuk menggabungkan dua koleksi secara logik di Java tanpa membuat rujukan tambahan pada objek yang terdapat di dalamnya.

Kod untuk tutorial ini terdapat di Github.