Bir Listeyi Java'da bir Sete dönüştürmenin en kolay yolu


628

Bir dönüştürmek için en kolay yolu nedir Lista SetJava?

Yanıtlar:


1065
Set<Foo> foo = new HashSet<Foo>(myList);

3
Doğru Bu cevap tuzaklar hangi bağlı olarak burada olduğundan, en iyi / kabul edilen cevap olma garanti etmek için yeterli teknik bağlamı yoksun olsa da, uygulamaları Setve Mapbir uygulamanın kullandığı; burada HashSetolduğu varsayılır .
Madbreaks

145

Sepp2k ile hemfikirim, ancak önemli olabilecek bazı detaylar var:

new HashSet<Foo>(myList);

size yinelemeleri olmayan sıralanmamış bir küme verecektir. Bu durumda, çoğaltma, nesnelerinizdeki .equals () yöntemi kullanılarak tanımlanır. Bu, .hashCode () yöntemiyle birlikte yapılır. (Eşitlik hakkında daha fazla bilgi için buraya bakın )

Sıralı küme veren bir alternatif:

new TreeSet<Foo>(myList);

Foo Karşılaştırılabilir'i uygularsa bu işe yarar. Yoksa, bir karşılaştırıcı kullanmak isteyebilirsiniz:

Set<Foo> lSet = new TreeSet<Foo>(someComparator);
lSet.addAll(myList);

Bu, benzersizliği sağlamak için CompareTo () (karşılaştırılabilir arabirimden) veya Compare () (karşılaştırıcıdan) değerlerine bağlıdır. Yani, sadece benzersizliği önemsiyorsanız, HashSet'i kullanın. Sıralamadan sonra iseniz, TreeSet'i düşünün. (Unutmayın: Daha sonra optimize edin!) Zaman verimliliği önemliyse, alan verimliliği önemliyse bir HashSet kullanın, TreeSet'e bakın. Set ve Map'in daha verimli uygulamalarının Trove (ve diğer yerler) aracılığıyla sağlandığını unutmayın.


Özel Karşılaştırıcı kullanım kutusunu dahil ettiğiniz için teşekkürler!
Justin Papez

70

Eğer kullanırsanız Guava kütüphanesi:

Set<Foo> set = Sets.newHashSet(list);

ya da daha iyisi:

Set<Foo> set = ImmutableSet.copyOf(list);

2
ImmutableSet.copyOf neden daha iyi?
user672009

1
Guava'nın newHashSet () yönteminin temel java yeni HashSet () üzerinde ne gibi avantajları vardır?
Nelda.techspiress

@ Nelda.techspiress Javadoc , yöntemin ne zaman kullanılması veya kullanılmaması gerektiğini tartışır. Son bölüme dikkat edin: bu yöntem çok kullanışlı değildir ve gelecekte kullanımdan kaldırılacaktır. Biraz şaşırmış olmama rağmen, tutarlılık bir faktör olarak bahsedilmiyor ImmutableSet.of(), örneğin olduğu gibi. EDIT: tüm aşırı yükler gereksiz olduğundan faktör olmayabilir .
shmosel

1
Hey @shmosel referansı için teşekkürler, ama daha çok ampirik bilgi arıyordum. Guava'yı kullananlar için neden Guava HashSet üzerinden seçilsin ki?
Nelda.techspiress

27

Java 8'i kullanarak akışı kullanabilirsiniz:

List<Integer> mylist = Arrays.asList(100, 101, 102);
Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));

10
Bu konuda performans cezasını kontrol ettiniz mi? bu, yinelenebilir bir + yineleyici, yeni bir HashSet () ve ardından her liste öğesi için yeni kümede bir addAll () çağrısı yapar. Genel olarak, cca. Yeni bir HashSet (liste) kadar basit bir şey için oluşturulan 5 nesne.
Agoston Horvath

1
@AgostonHorvath Yorumunuz için teşekkür ederiz. Buraya geldiğimde aslında bu bilgiyi arıyordum.
TheRealChx101

17
Set<E> alphaSet  = new HashSet<E>(<your List>);

veya tam örnek

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ListToSet
{
    public static void main(String[] args)
    {
        List<String> alphaList = new ArrayList<String>();
        alphaList.add("A");
        alphaList.add("B");
        alphaList.add("C");
        alphaList.add("A");
        alphaList.add("B");
        System.out.println("List values .....");
        for (String alpha : alphaList)
        {
            System.out.println(alpha);
        }
        Set<String> alphaSet = new HashSet<String>(alphaList);
        System.out.println("\nSet values .....");
        for (String alpha : alphaSet)
        {
            System.out.println(alpha);
        }
    }
}

1
Tam bir kod örneği için +1. Buradaki ek bir not, karma işlemin çalışmadan koşmaya aynı olacağı garanti edilmez. Bu, 'Değerleri ayarla .....' öğesinden sonra yazdırılan listenin bir çalışma 'ABC' ve başka bir çalışma 'CBA' olabileceği anlamına gelir. Cevabımda bahsettiğim gibi, istikrarlı bir sipariş almak için bir ağaç seti kullanabilirsiniz. Başka bir seçenek, öğelerin kendisine eklendiği sırayı hatırlayan LinkedHashSet kullanmak olacaktır.
Spina

8

Sete dönüştürmeden önce bir Null kontrolü yapardım.

if(myList != null){
Set<Foo> foo = new HashSet<Foo>(myList);
}

3
VeyaSet<Foo> foo = myList == null ? Collections.emptySet() : new HashSet<Foo>(myList);
vegemite4me

6

Sen dönüştürebilirsiniz List<>içinSet<>

Set<T> set=new HashSet<T>();

//Added dependency -> If list is null then it will throw NullPointerExcetion.

Set<T> set;
if(list != null){
    set = new HashSet<T>(list);
}

Sanırım onu ​​List'ten Set'e yayınlamak istedin.
Simon

6

Java 8 için çok kolay:

List < UserEntity > vList= new ArrayList<>(); 
vList= service(...);
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet());

"Gerçek" Java 8 new ArrayList<>();-) kullanmak olurdu
JR

6

Java - addAll

set.addAll(aList);

Java - yeni Nesne

new HashSet(list)

Java-8

list.stream().collect(Collectors.toSet());

Guva Kullanımı

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

Nispeten yeni arkadaşımızı unutmayalım, akış API'sı. Listeye bir kümeye dönüştürmeden önce önişleme yapmanız gerekiyorsa, şöyle bir şeye sahip olmak daha iyidir:

list.stream().<here goes some preprocessing>.collect(Collectors.toSet());

4

Yapıcıyı kullanmanın en iyi yolu

Set s= new HashSet(list);

Java 8'de aynı zamanda stream api ::

Set s= list.stream().collect(Collectors.toSet());

3

SetAs almanın çeşitli yolları vardır :

    List<Integer> sourceList = new ArrayList();
    sourceList.add(1);
    sourceList.add(2);
    sourceList.add(3);
    sourceList.add(4);

    // Using Core Java
    Set<Integer> set1 = new HashSet<>(sourceList);  //needs null-check if sourceList can be null.

    // Java 8
    Set<Integer> set2 = sourceList.stream().collect(Collectors.toSet());
    Set<Integer> set3 = sourceList.stream().collect(Collectors.toCollection(HashSet::new));

    //Guava
    Set<Integer> set4 = Sets.newHashSet(sourceList);

    // Apache commons
    Set<Integer> set5 = new HashSet<>(4);
    CollectionUtils.addAll(set5, sourceList);

Kullandığımız zaman Collectors.toSet()bir dizi döner ve doc göre: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Eğer bir tane almak istiyorsak, HashSetbir set (kontrol set3) almak için diğer alternatifi kullanabiliriz .


3

Java 10 ile artık a'yı değiştirilemez Set#copyOfhale kolayca dönüştürmek için List<E>kullanabilirsiniz Set<E>:

Misal:

var set = Set.copyOf(list);

Bu bir sırasız işlemdir ve unutmayın nullelemanları vardır değil bir atacağım olarak, izin verilen NullPointerException.

Değiştirilebilir olmasını istiyorsanız, bunu yapıcıya bir Setuygulama olarak iletin.


2

İle daha fazla Java 8 esnek çözümü Optional.ofNullable

Set<Foo> mySet = Optional.ofNullable(myList).map(HashSet::new).orElse(null);

2

Eğer kullanırsanız Eclipse Koleksiyon :

MutableSet<Integer> mSet = Lists.mutable.with(1, 2, 3).toSet();
MutableIntSet mIntSet = IntLists.mutable.with(1, 2, 3).toSet();

MutableSetArayüzü uzanır java.util.Setise MutableIntSetarayüz değildir. Ayrıca herhangi Iterablebirini fabrika sınıfını Setkullanarak bir dönüştürebilirsiniz Sets.

Set<Integer> set = Sets.mutable.withAll(List.of(1, 2, 3));

Eclipse Koleksiyonlarında bulunan değiştirilebilir fabrikalar hakkında daha fazla açıklama var .

Bir istiyorsan ImmutableSetbir gelen Listkullanabileceğiniz Setsaşağıdaki gibi fabrika:

ImmutableSet<Integer> immutableSet = Sets.immutable.withAll(List.of(1, 2, 3))

Not: Eclipse Collections için bir komisyoncuyum


0

Liste yinelemeleri kaldırdığından, Liste yinelemeleri desteklediğinden, ancak Set Java'daki yinelemeleri desteklemediğinden, Listeden Set'e dönüştürmenin koleksiyondaki yinelemeleri kaldıracağını unutmayın.

Doğrudan Dönüşüm: Bir Listeyi Kümeye dönüştürmenin en yaygın ve basit yolu

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Converting a list to set
Set<String> set = new HashSet<>(list);

Apache Commons Koleksiyonları: Bir Listeyi Kümeye dönüştürmek için Commons Koleksiyonları API'sını da kullanabilirsiniz: -

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Creating a set with the same number of members in the list 
Set<String> set = new HashSet<>(4);

// Adds all of the elements in the list to the target set
CollectionUtils.addAll(set, list);

Akış kullanma: Başka bir yol, verilen listeyi akışa dönüştürmek, ardından ayarlamak için akış yapmaktır:

// Creating a list of strings 
List<String> list = Arrays.asList("One", "Two", "Three", "Four"); 

// Converting to set using stream 
Set<String> set = list.stream().collect(Collectors.toSet()); 
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.