Menukar Koleksi ke ArrayList di Java

1. Gambaran keseluruhan

Menukar koleksi Java dari satu jenis ke jenis lain adalah tugas pengaturcaraan yang biasa. Dalam tutorial ini, kita akan menukar sebarang jenis Koleksi ke ArrayList .

Sepanjang tutorial, kami akan menganggap bahawa kami sudah mempunyai koleksi objek Foo . Dari sana, kami akan membuat ArrayList menggunakan pelbagai pendekatan.

2. Menentukan Contoh Kita

Tetapi sebelum meneruskan, mari kita modelkan input dan output kita.

Sumber kami boleh menjadi jenis koleksi jadi kami akan menyatakannya menggunakan antara muka Koleksi :

Collection srcCollection; 

Kita perlu menghasilkan ArrayList dengan jenis elemen yang sama:

ArrayList newList;

3. Menggunakan ArrayList Constructor

Kaedah paling mudah untuk menyalin koleksi ke koleksi baru adalah menggunakan konstruktornya.

Dalam panduan sebelumnya untuk ArrayList, kami mengetahui bahawa pembina ArrayList dapat menerima parameter koleksi:

ArrayList newList = new ArrayList(srcCollection);
  • ArrayList baru mengandungi salinan unsur Foo yang cetek dalam koleksi sumber.
  • Urutannya sama dengan yang ada dalam koleksi sumber.

Kesederhanaan konstruktor menjadikannya pilihan terbaik dalam kebanyakan senario.

4. Menggunakan API Aliran

Sekarang, mari kita manfaatkan Streams API untuk membuat ArrayList dari Koleksi yang ada :

ArrayList newList = srcCollection.stream().collect(toCollection(ArrayList::new));

Dalam coretan ini:

  • Kami mengambil aliran dari koleksi sumber dan menggunakan operator collect () untuk membuat Daftar
  • Kami menentukan ArrayList :: baru untuk mendapatkan jenis senarai yang kami mahukan
  • Kod ini juga akan menghasilkan salinan cetek.

Sekiranya kami tidak prihatin dengan jenis Daftar yang tepat , kami dapat mempermudah:

List newList = srcCollection.stream().collect(toList());

Perhatikan bahawa toCollection () dan toList () diimport secara statik dari Pemungut . Untuk mengetahui lebih lanjut, sila rujuk panduan kami mengenai Java 8's Collectors.

5. Salinan Dalam

Sebelum kita menyebut "salinan cetek". Oleh itu, kami bermaksud bahawa elemen dalam senarai baru adalah contoh Foo yang sama yang masih ada dalam koleksi sumber. Oleh itu, kami telah menyalin Foo ke Daftar baru dengan merujuk.

Sekiranya kita mengubah isi instance Foo dalam salah satu koleksi, pengubahsuaian tersebut akan tercermin dalam kedua koleksi tersebut . Oleh itu, jika kita mahu mengubah elemen dalam kedua-dua koleksi tanpa mengubah yang lain, kita perlu melakukan "salinan dalam"

Untuk menyalin Foo secara mendalam , kami membuat contoh Foo yang baru untuk setiap elemen . Akibatnya, semua medan Foo perlu disalin ke contoh baru.

Mari tentukan kelas Foo kami supaya tahu cara menyalinnya sendiri:

public class Foo { private int id; private String name; private Foo parent; public Foo(int id, String name, Foo parent) { this.id = id; this.name = name; this.parent = parent; } public Foo deepCopy() { return new Foo( this.id, this.name, this.parent != null ? this.parent.deepCopy() : null); } }

Di sini kita boleh melihat medan yang id dan nama adalah int dan tali . Jenis data ini disalin mengikut nilai. Oleh itu, kita hanya boleh menetapkan kedua-duanya.

Bidang induk adalah Foo lain , yang merupakan kelas. Sekiranya Foo dimutasi, sebarang kod yang berkongsi rujukan itu akan dipengaruhi oleh perubahan ini. Kita mesti menyalin bidang induk secara mendalam .

Sekarang kita dapat kembali ke penukaran ArrayList kami . Kami hanya memerlukan pengendali peta untuk memasukkan salinan mendalam ke dalam aliran:

ArrayList newList = srcCollection.stream() .map(foo -> foo.deepCopy()) .collect(toCollection(ArrayList::new));

Kita boleh mengubah kandungan kedua-dua koleksi tanpa mempengaruhi yang lain.

Salinan mendalam boleh menjadi proses yang panjang bergantung pada jumlah elemen dan kedalaman data. Menggunakan aliran selari di sini dapat memberikan peningkatan prestasi jika diperlukan.

6. Mengawal Urutan Daftar

Secara lalai, aliran kami akan menghantar elemen ke ArrayList kami dalam urutan yang sama seperti yang ditemui dalam koleksi sumber.

Sekiranya kita mahu mengubah pesanan itu, kita boleh menggunakan operator yang diurutkan ke aliran . Untuk menyusun objek Foo kami dengan nama:

ArrayList newList = srcCollection.stream() .sorted(Comparator.comparing(Foo::getName)) .collect(toCollection(ArrayList::new));

Kami boleh mendapatkan maklumat lebih lanjut mengenai pesanan aliran dalam tutorial sebelumnya.

7. Kesimpulannya

The ArrayList pembina adalah cara yang berkesan untuk mendapatkan kandungan yang Collection menjadi baru ArrayList .

However, if we need to tweak the resulting list, the Streams API provides a powerful way to modify the process.

The code used in this article can be found in its entirety over on GitHub.