2009-09-15 11 views

Odpowiedz

813
Set<Foo> foo = new HashSet<Foo>(myList); 
+52

Spowoduje to wygenerowanie wyjątku NullPointerException, jeśli lista będzie pusta. – Ashish

+87

@Ashish: To nie ma znaczenia dla pytania. Nikt nie pytał, jak przekonwertować null na Set. Ludzie zawsze wymagający obsługi null to znak, jak złamana jest Java (kultura). Prawie zawsze null jest błędem. WYRÓŻNIENIE WYJĄTKU JEST RZECZYWIŚCIE NAJLEPSZE, KTÓREGO MOŻESZ ZROBIĆ. Zwłaszcza gdy jest to zerowe odniesienie do kolekcji: jak często można sobie wyobrazić semantyczne znaczenie odwołań zerowych do kolekcji - i takie, że znaczenie różni się od pustej kolekcji? –

+2

Uzgodnione, zamiast wartości NULL, należy (prawie) zawsze przekazywać: niezmienne statyczne, puste wystąpienia twoich ziaren, lub Collections.emptyXXX() dla twoich kolekcji. Dzięki temu Twój kod jest dużo łatwiejszy do odczytania, jeśli nie jest zanieczyszczony zerowymi kontrolami na początku każdej metody. –

112

zgadzam się z sepp2k, ale istnieje kilka innych szczegółów, które mogłyby Dziedzina:

new HashSet<Foo>(myList); 

daje niesegregowanych zestaw, który nie ma duplikatów. W tym przypadku duplikacja jest identyfikowana za pomocą metody .equals() na twoich obiektach. Odbywa się to w połączeniu z metodą .hashCode(). (Więcej informacji na temat równości wyglądać here)

Alternatywą, która daje posortowaną zestawu wynosi:

new TreeSet<Foo>(myList); 

Działa to czy Foo implementuje porównywalne. Jeśli nie wtedy może chcieć użyć komparatora:

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

to zależy od obu CompareTo() (z porównywalnym Interface) lub porównać() (od komparatora), aby zapewnić niepowtarzalność. Jeśli więc zależy Ci tylko na wyjątkowości, użyj HashSet. Jeśli chcesz sortować, weź pod uwagę TreeSet. (Pamiętaj: Optymalizuj później!) Jeśli liczy się efektywność czasu, użyj HashSet, jeśli ważna jest wydajność miejsca, spójrz na TreeSet. Zauważ, że wydajniejsze implementacje Set i Map są dostępne przez Trove (i inne lokalizacje).

58

Jeśli używasz Guava Biblioteka:

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

albo lepiej:

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

+1 za użycie ImmutableSet – tomrozb

+1

Dlaczego ImmutableSet.copyOf jest lepszy? – user672009

+1

Jakie zalety ma newHashSet() Guavy nad podstawową java new HashSet()? –

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

lub kompletny 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 dla pełnego przykładu kodu. Jedną dodatkową uwagą jest to, że nie ma gwarancji, że hashing będzie taki sam, od uruchomienia do uruchomienia. Oznacza to, że lista wydrukowana po "Ustaw wartościach ....." może być "ABC" jeden bieg, a "CBA" kolejny bieg. Jak wspomniałem w mojej odpowiedzi, można użyć zestawu drzew, aby uzyskać stabilne zamówienie. Inną opcją byłoby użycie obiektu LinkedHashSet, który zapamiętuje kolejność dodawania elementów do niego. – Spina

9

chciałbym wykonać Null czek przed konwersją ustawić .

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

Lub 'Set foo = myList == null? Collections.emptySet(): new HashSet (myList); ' – vegemite4me

5

Można konwertować List<> do Set<>

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

Myślę, że chodziło Ci o przeniesienie go z List do Set. – Simon

17

Korzystanie Java 8 można użyć strumienia:

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

Czy sprawdziłeś na tym kary? to zrobiłby iteracyjny + iterator, nowy HashSet(), a następnie dla każdego elementu listy, wywołanie addAll() w nowym zestawie. Ogólnie rzecz biorąc, cca. 5 obiektów utworzonych dla czegoś tak prostego jak nowy HashSet (lista). –

2

Istnieją różne sposoby, aby uzyskać Set jak:

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

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

3

Dla Java 8 to bardzo proste:

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

Nie zapominajmy naszego stosunkowo nowego przyjaciela, strumienia API. Jeśli potrzebujesz listy Preprocesuj przed przekształceniem go do zestawu, to lepiej mieć coś takiego:

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

Bardziej Java 8 sprężysta rozwiązanie z Optional.ofNullable

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

Z Java 10, można teraz używać Set#copyOf łatwo przekształcić List<E> do niezmienne Set<E>:

przykład:

var set = Set.copyOf(list); 

Należy pamiętać, że ta operacja jest nieuporządkowana i null elementy są nie dozwolone, ponieważ będzie ona rzucać NullPointerException.

Jeśli chcesz, aby można było go modyfikować, po prostu prześlij go do konstruktora implementacji Set.

Powiązane problemy