Bir Kümeyi <T> bir Listeye <T> dönüştürmenin en kısa yolu


201

Örneğin, şu anda bunu yapıyorum:

Set<String> setOfTopicAuthors = ....

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

Bunu yenebilir misin?


2
Kullanım java.util.Collection: O (0)
Tim

@Carl, Set'i Liste gerektiren bir 3. taraf arayüzüne göndermem gerekiyor. @Tim Keşke Koleksiyon kullanmak için 3. taraf arayüzünü değiştirebilseydim.
Jacques René Mesrine

1
Anlıyorum; tuhaf kısıtlamalardan kaçınmak için Roger'ın cevabı ile giderdim. Yine de, Listeyi gerçekten tekrar kullanmadığınız sürece, onu herhangi bir şeye atamayı (yani, foo.api (list)) yerine foo.api (yeni ArrayList <String> (listOfTopicAuthors)) kullanmayı atlarım.
Carl

2
@ JacquesRenéMesrine: Söz konusu kodun ilk satırı yanıltıcı: Beklenen: Set<String> setOfTopicAuthors = ....Gerçek:Set<String> listOfTopicAuthors = ....
realPK

Ya da aynı List<String> list = Arrays.asList(setOfTopicAuthors.toArray(String[]::new))cevabı yapmanın alternatif bir yolu , bağlantılı cevapta detaylandırılabilir.
Naman

Yanıtlar:


432
List<String> list = new ArrayList<String>(listOfTopicAuthors);

1
... ve böylece Java kod kurallarına radikal bir şekilde meydan okuyor: oracle.com/technetwork/java/javase/documentation/… ! :) :)
Håvard Geithus

Bundan sonra bana hata vererek liste elemanına erişmeye çalıştığımda, "java.lang.ClassCastException: java.lang.Integer java.lang.String için kullanılamaz" .. don; nedenini bilmiyorum .. bu basit list.get (int) bu kadar ... herhangi bir öneriniz var mı?
CoDe

2
Java 7 ve üstü için tür parametresini vermek için atlayabilirsiniz ArrayList: List<String> l = new ArrayList<>(listOfTopicAuthors); En özlü bir dış kütüphane kullanmadan?
Brett Duncavage

listOfTopicAuthorsBoş olması durumunda NullPointerException özel durumunu atacaktır .
w35l3y

91
List<String> l = new ArrayList<String>(listOfTopicAuthors);

4
kabul edilen cevapla aynı anda cevap vermek ve krediyi alamamak için. +1
jayeffkay

@Adamski Ben endeksi 0 yerine 1 ile başlayan bir liste ile sonuçlandı, herhangi bir ilaç?
Jack

1
@Jack: Kesinlikle böyle olmayacak. Java.util.List içindeki Javadoc'tan: "Listeler (Java dizileri gibi) sıfır tabanlıdır."
Adamski

@Adamski Yanıt için teşekkürler. Listelerin olması gerektiğini ve sıfır tabanlı olduğunu biliyorum, bu yüzden bu benim için çok garip. Setimi bir listeye dönüştürdükten sonra, foreach, sort vb. dizin 1'de başlar. Ancak, normal bir liste oluşturursam dizin 0'da başlar.
Jack

1
@Jack: Kulağa çok garip geliyor. Kodunuzu ayrı bir soru olarak gönderirseniz, eminim birileri size yardımcı olabilir.
Adamski

23

Sahip olduğumuzu göz önünde bulundurarak Set<String> stringSetaşağıdakileri kullanabiliriz:

Java 10 (Değiştirilemez liste)

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

Java 8 (Değiştirilebilir Listeler)

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

Yöntem için doc başınatoList()

Döndürülen Listenin türü, değiştirilebilirliği, serileştirilebilirliği veya iş parçacığı güvenliği konusunda hiçbir garanti yoktur; döndürülen Liste üzerinde daha fazla denetim gerekiyorsa, toCollection (Tedarikçi) öğesini kullanın.

Yani belirli bir uygulamaya ihtiyacımız olursa, örneğin ArrayListbu şekilde elde edebiliriz:

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

Java 8 (Değiştirilemez Listeler)

Collections::unmodifiableListYöntemi kullanabilir ve önceki örneklerde döndürülen listeyi kapatabiliriz . Ayrıca kendi özel yöntemimizi yazabiliriz:

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);
        }
}

Ve sonra şu şekilde kullanın:

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

Başka bir olasılık, collectingAndThensonuç döndürülmeden önce bazı nihai dönüşümlerin yapılmasına izin veren yöntemi kullanmaktır :

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

Dikkat edilmesi gereken bir nokta , yöntemin Collections::unmodifiableList, dokümana göre belirtilen listenin değiştirilemez bir görünümünü döndürmesidir . Değiştirilemez bir görünüm koleksiyonu değiştirilemeyen ve aynı zamanda bir destek koleksiyonuna bir görünümdür. Destek koleksiyonunda değişikliklerin hala mümkün olabileceğini ve gerçekleşmeleri durumunda değiştirilemeyen görünümden görülebileceğini unutmayın. Ancak toplayıcı yöntemi Java 10'daCollectors.unmodifiableList gerçekten değişmez bir liste döndürür .


Ben dönüştürmek için bu kullanılan Set<Double>bir etmek List<Doubleseti nereden geldiğini, LinkedHashMapbireyin .keySet()yöntemle. Eclipse bana bir tür uyuşmazlığı olduğunu ve 'den' Objecte dönüşemediğimi söyledi List<Double>. Bunun neden olabileceğini söyleyebilir misiniz? Dökerek etrafta dolaştım, ama neden olduğunu merak ediyordum.
Ungeheuer

1
Evet, Java Geliştiricileri gittikçe daha fazla Java 8 özelliği kullanmaları gerektiğinden, bu yanıt yukarıdaki 2 yanıttan daha iyidir.
Shubham Pandey

13

Set için şunu deneyin :

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

Harita için şunu deneyin :

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());

2

Guava kullanıyorsanız newArrayList, Listeler sınıfından statik olarak yöntemi içeri aktarırsınız :

List<String> l = newArrayList(setOfAuthors);

0

tam olarak kodunuzun bağlamı üzerinden ne yaptığınızdan emin değilim ama ...

neden listOfTopicAuthorsdeğişkeni yapmak ?

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

"....", setinizin yeni veya başka bir yerden gelip gelmediğini gösterir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.