Najprostszym sposobem na konwersję listy do zestawu w Javie


627

Jaki jest najłatwiejszy sposób przekonwertowania pliku ListA Setna język Java?

Odpowiedzi:


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

3
Chociaż poprawna, ta odpowiedź nie ma wystarczającego kontekstu technicznego, aby zagwarantować, że jest to najlepsza / zaakceptowana odpowiedź, ponieważ istnieją pułapki w zależności od tego, które implementacje Seti Mapjedna z nich używa; HashSetjest założyć tutaj.
Madbreaks

145

Zgadzam się z sepp2k, ale istnieją inne szczegóły, które mogą mieć znaczenie:

new HashSet<Foo>(myList);

da ci nieposortowany zestaw, który nie ma duplikatów. W takim przypadku duplikacja jest identyfikowana za pomocą metody .equals () na twoich obiektach. Odbywa się to w połączeniu z metodą .hashCode (). (Aby uzyskać więcej informacji na temat równości, patrz tutaj )

Alternatywą, która daje posortowany zestaw, jest:

new TreeSet<Foo>(myList);

Działa to, jeśli Foo implementuje porównywalne. Jeśli tak nie jest, możesz użyć komparatora:

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

Zależy to od funkcji CompareTo () (z porównywalnego interfejsu) lub Compare () (z komparatora), aby zapewnić unikalność. Jeśli więc zależy Ci na wyjątkowości, skorzystaj z zestawu HashSet. Jeśli chcesz posortować, rozważ zestaw TreeSet. (Pamiętaj: zoptymalizuj później!) Jeśli liczy się efektywność czasu, użyj HashSet, jeśli liczy się wydajność przestrzeni, spójrz na TreeSet. Zauważ, że bardziej wydajne wdrożenia Set i Map są dostępne za pośrednictwem Trove (i innych lokalizacji).


Dzięki za dołączony niestandardowy przypadek użycia Komparatora!
Justin Papez,

70

Jeśli korzystasz z biblioteki Guava :

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

albo lepiej:

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

2
Dlaczego ImmutableSet.copyOf jest lepszy?
user672009 14.04.16

1
Jakie zalety ma newHashSet () Guava w porównaniu z podstawową nową Javą HashSet ()?
Nelda.techspiress

@ Nelda.techspiress W javadoc dyskutuje się, kiedy należy zastosować metodę. Zwróć uwagę na ostatnią część: ta metoda nie jest zbyt przydatna i prawdopodobnie będzie przestarzała w przyszłości. Chociaż jestem nieco zaskoczony, spójność nie jest wspomniana jako czynnik, jak ImmutableSet.of()na przykład w przypadku. EDYCJA: to może nie być czynnik, ponieważ wszystkie przeciążenia są niepotrzebne.
shmosel

1
Hej, dziękuję za referencję @shmosel, ale szukałem bardziej wiedzy empirycznej. Dla tych, którzy używali Guawy, dlaczego Guawa miałaby zostać wybrana zamiast HashSet?
Nelda.techspiress

27

Za pomocą java 8 możesz korzystać ze strumienia:

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

10
Czy sprawdziłeś już karę wydajności? zrobiłoby to iterowalny + iterator, nowy HashSet (), a następnie dla każdego elementu listy wywołanie addAll () w nowym zestawie. Ogólnie ok. 5 obiektów utworzonych dla czegoś tak prostego jak nowy zestaw HashSet (lista).
Agoston Horvath,

1
@AgostonHorvath Dziękujemy za komentarz. Pierwotnie szukałem tych informacji, kiedy tu przybyłem.
TheRealChx101

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

lub pełny przykład

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
+1 za pełny przykład kodu. Jedna dodatkowa uwaga tutaj jest taka, że ​​hashowanie nie jest takie samo w poszczególnych biegach. Oznacza to, że lista wydrukowana po „Ustaw wartości .....” może być „ABC” w jednym przebiegu, a „CBA” w innym przebiegu. Jak wspomniałem w mojej odpowiedzi, możesz użyć zestawu drzew, aby uzyskać stabilne uporządkowanie. Inną opcją byłoby użycie LinkedHashSet, który pamięta kolejność dodawania elementów.
Spina,

8

Wykonałbym sprawdzanie wartości Null przed konwersją na set.

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

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

6

Możesz przekonwertować List<>naSet<>

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

Myślę, że miałeś na myśli przesyłanie go z listy do zestawu.
Simon

6

W przypadku Java 8 jest to bardzo łatwe:

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

Można użyć „prawdziwej” Java 8 new ArrayList<>();-)
JR

6

Java - addAll

set.addAll(aList);

Java - nowy obiekt

new HashSet(list)

Java-8

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

Korzystanie z Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

Nie zapominajmy o naszym stosunkowo nowym przyjacielu, Stream API. Jeśli musisz wstępnie przetworzyć listę przed przekonwertowaniem jej na zestaw, lepiej mieć coś takiego:

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

4

Najlepszy sposób na użycie konstruktora

Set s= new HashSet(list);

W java 8 możesz również używać interfejsu API streamu:

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

3

Istnieją różne sposoby uzyskania Setjako:

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

Gdy używamy Collectors.toSet()zwraca zestaw i zgodnie doc: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Jeśli chcemy uzyskać zestaw HashSet, możemy użyć innej alternatywy, aby uzyskać zestaw (sprawdź set3).


3

W Javie 10 możesz teraz Set#copyOfłatwo przekonwertować plik List<E>na niemodyfikowalny Set<E>:

Przykład:

var set = Set.copyOf(list);

Należy pamiętać, że jest to operacja nieuporządkowana, a nullelementy nie są dozwolone, ponieważ spowoduje to rzut NullPointerException.

Jeśli chcesz, aby można go było modyfikować, po prostu przekaż go konstruktorowi Setimplementacji.


2

Bardziej odporne rozwiązanie Java 8 z Optional.ofNullable

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

2

Jeśli korzystasz z kolekcji Eclipse :

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

MutableSetInterfejs rozszerza java.util.Setnatomiast MutableIntSetinterfejs nie. Można również przekonwertować dowolny IterableDo Setkorzystania z Setsklasy fabrycznej.

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

Więcej wyjaśnień dotyczących modyfikowalnych fabryk dostępnych jest w Eclipse Collections tutaj .

Jeśli chcesz ImmutableSetod List, możesz użyć Setsfabryki w następujący sposób:

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

Uwaga: jestem osobą odpowiedzialną za kolekcje Eclipse


0

Pamiętaj, że konwersja z listy do zestawu usunie duplikaty z kolekcji, ponieważ lista obsługuje duplikaty, ale zestaw nie obsługuje duplikatów w Javie.

Bezpośrednia konwersja: najczęstszy i najprostszy sposób konwersji listy na zestaw

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

Kolekcje Apache Commons: możesz także użyć interfejsu API Commons Commons do konwersji listy na zestaw: -

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

Korzystanie ze strumienia: Innym sposobem jest konwersja podanej listy do strumienia, a następnie strumieniowanie w celu ustawienia: -

// 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()); 
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.