Cara paling ringkas untuk mengonversi Set <T> ke Daftar <T>

201

Misalnya, saya sedang melakukan ini:

Set<String> setOfTopicAuthors = ....

List<String> list = Arrays.asList( 
    setOfTopicAuthors.toArray( new String[0] ) );

Bisakah kamu mengalahkan ini?

Jacques René Mesrine
sumber
2
Gunakan java.util.Collection: O (0)
Tim
@Carl, saya harus mengirimkan Set ke antarmuka pihak ke-3 yang membutuhkan Daftar. @Tim Saya berharap saya bisa mengubah antarmuka pihak ke-3 untuk menggunakan Koleksi.
Jacques René Mesrine
1
Saya melihat; kecuali ada kendala aneh, saya akan pergi dengan jawaban Roger. Meskipun, kecuali jika Anda benar-benar menggunakan Daftar lagi, saya akan melewatkan menugaskannya untuk apa pun (yaitu, gunakan foo.api (ArrayList <String> baru (listOfTopicAuthors)) alih-alih foo.api (daftar)).
Carl
2
@ JacquesRenéMesrine: Baris pertama dari kode yang dimaksud menyesatkan: Diharapkan: Set<String> setOfTopicAuthors = ....Aktual:Set<String> listOfTopicAuthors = ....
realPK
Atau cara alternatif untuk melakukan hal yang sama bisa List<String> list = Arrays.asList(setOfTopicAuthors.toArray(String[]::new)), dirinci dalam jawaban yang ditautkan.
Naman

Jawaban:

432
List<String> list = new ArrayList<String>(listOfTopicAuthors);
Schildmeijer
sumber
1
... dan dengan demikian secara radikal menentang konvensi kode Java: oracle.com/technetwork/java/javase/documentation/… ! :) :)
Håvard Geithus
setelah ini ketika saya mencoba mengakses elemen daftar itu memberi saya kesalahan, "java.lang.ClassCastException: java.lang.Integer tidak dapat dilemparkan ke java.lang.String" ..don; t tahu mengapa .. itu daftar sederhana. get (int) itu saja ... ada saran?
CoDe
2
Saya percaya pada Java 7 dan di atas Anda dapat menghilangkan parameter tipe untuk ArrayListmenghasilkan: List<String> l = new ArrayList<>(listOfTopicAuthors); Paling ringkas tanpa menggunakan perpustakaan eksternal?
Brett Duncavage
Ini akan melempar NullPointerException jika listOfTopicAuthorsnull.
w35l3t
91
List<String> l = new ArrayList<String>(listOfTopicAuthors);
Adamski
sumber
4
untuk menjawab pada menit yang sama dengan jawaban yang diterima dan tidak mendapatkan kredibilitas. +1
jayeffkay
@Adamski Saya berakhir dengan daftar yang indeksnya dimulai pada 1 bukannya 0, ada obatnya?
Jack
1
@ Jack: Itu pasti tidak akan terjadi. Dari Javadoc dari java.util.List: "Daftar (seperti array Java) berbasis nol."
Adamski
@Adamski Terima kasih atas tanggapannya. Saya tahu daftar harus dan berbasis nol itulah sebabnya ini sangat aneh bagi saya. Setelah mengonversi set saya ke daftar, saya tidak bisa melakukan operasi berulang-ulang untuk itu terlebih dahulu, mengurutkan, dll. Saya mendapatkan NullPointerException, namun ketika saya berharap daftar saya tidak ada elemen yang nol, dan satu-satunya yang aneh yang saya perhatikan adalah bahwa indeks dimulai pada 1. Namun, jika saya hanya membuat daftar normal indeks dimulai pada 0. Aneh?
Jack
1
@ Jack: Kedengarannya sangat aneh. Jika Anda memposting kode Anda sebagai pertanyaan terpisah, saya yakin seseorang akan dapat membantu Anda.
Adamski
23

Mengingat yang kita miliki, Set<String> stringSetkita dapat menggunakan yang berikut:

Java 10 (daftar tidak dapat diverifikasi)

List<String> strList = stringSet.stream().collect(Collectors.toUnmodifiableList());

Java 8 (Daftar yang Dapat Diubah)

import static java.util.stream.Collectors.*;
List<String> stringList1 = stringSet.stream().collect(toList());

Sesuai dokumen untuk metode initoList()

Tidak ada jaminan pada jenis, mutabilitas, serializability, atau keamanan thread dari Daftar yang dikembalikan; jika kontrol lebih besar atas Daftar yang dikembalikan diperlukan, gunakan toCollection (Pemasok).

Jadi jika kita membutuhkan implementasi spesifik misalnya ArrayListkita bisa mendapatkannya dengan cara ini:

List<String> stringList2 = stringSet.stream().
                              collect(toCollection(ArrayList::new));

Java 8 (Daftar Tidak Diubah)

Kita dapat menggunakan Collections::unmodifiableListmetode dan membungkus daftar yang dikembalikan pada contoh sebelumnya. Kami juga dapat menulis metode khusus kami sebagai:

class ImmutableCollector {
    public static <T> Collector<T, List<T>, List<T>> toImmutableList(Supplier<List<T>> supplier) {
            return Collector.of( supplier, List::add, (left, right) -> {
                        left.addAll(right);
                        return left;
                    }, Collections::unmodifiableList);
        }
}

Dan kemudian menggunakannya sebagai:

List<String> stringList3 = stringSet.stream()
             .collect(ImmutableCollector.toImmutableList(ArrayList::new)); 

Kemungkinan lain adalah menggunakan collectingAndThenmetode yang memungkinkan beberapa transformasi akhir dilakukan sebelum mengembalikan hasil:

    List<String> stringList4 = stringSet.stream().collect(collectingAndThen(
      toCollection(ArrayList::new),Collections::unmodifiableList));

Satu hal yang perlu diperhatikan adalah bahwa metode ini Collections::unmodifiableListmengembalikan tampilan daftar yang ditentukan yang tidak dapat dimodifikasi, sesuai dok . Koleksi tampilan yang tidak dapat dimodifikasi adalah koleksi yang tidak dapat dimodifikasi dan juga merupakan tampilan ke koleksi dukungan. Perhatikan bahwa perubahan pada koleksi dukungan mungkin masih dimungkinkan, dan jika terjadi, mereka dapat dilihat melalui tampilan yang tidak dapat dimodifikasi. Tetapi metode kolektor Collectors.unmodifiableListmengembalikan daftar yang benar-benar tidak dapat diubah di Java 10 .

akhil_mittal
sumber
Saya menggunakan ini untuk mengkonversi Set<Double>ke List<Double, di mana set berasal dari LinkedHashMap's .keySet()metode. Eclipse mengatakan kepada saya bahwa ada jenis ketidakcocokan, dan bahwa saya tidak dapat mengkonversi dari Objectke List<Double>. Bisakah Anda memberi tahu saya mengapa ini terjadi? Saya mengatasinya dengan casting, tapi saya bertanya-tanya mengapa itu terjadi.
Ungeheuer
1
Ya, karena Java Developers seharusnya menggunakan lebih banyak fitur Java 8, jawaban ini lebih baik daripada 2 jawaban di atas.
Shubham Pandey
13

Coba ini untuk Set :

Set<String> listOfTopicAuthors = .....
List<String> setList = new ArrayList<String>(listOfTopicAuthors); 

Coba ini untuk Peta :

Map<String, String> listOfTopicAuthors = .....
// List of values:
List<String> mapValueList = new ArrayList<String>(listOfTopicAuthors.values());
// List of keys:
List<String> mapKeyList = new ArrayList<String>(listOfTopicAuthors.KeySet());
Prabhakar Manthena
sumber
2

Jika Anda menggunakan Guava, Anda mengimpor newArrayListmetode statis dari kelas Daftar :

List<String> l = newArrayList(setOfAuthors);
Andrejs
sumber
0

tidak benar-benar yakin apa yang Anda lakukan persis melalui konteks kode Anda tetapi ...

mengapa membuat listOfTopicAuthorsvariabel sama sekali?

List<String> list = Arrays.asList((....).toArray( new String[0] ) );

"...." mewakili namun set Anda ikut bermain, apakah itu baru atau berasal dari lokasi lain.

jp093121
sumber