2009-09-15 19 views

risposta

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

Questo genererà NullPointerException se l'elenco è nullo – Ashish

+87

@Ashish: Questo è completamente irrilevante per la domanda. Nessuno ha chiesto come convertire null in un Set. Le persone che richiedono sempre di gestire null sono un segno di quanto Java (cultura) sia infranto. Quasi sempre, null è un errore. LANCIARE UNA ECCEZIONE È REALMENTE IL MEGLIO CHE PUOI FARE. Soprattutto quando si tratta di un riferimento nullo a una raccolta: quanto spesso si può immaginare un significato semantico di riferimento nullo a una raccolta - e tale che il significato è diverso da una raccolta vuota? –

+2

Concordato, invece di null, dovresti (quasi) passare sempre: istanze statiche vuote immutabili dei tuoi bean o Collections.emptyXXX() per le tue raccolte. Rende anche il tuo codice molto più facile da leggere se non è inquinato con controlli null all'inizio di ogni metodo. –

112

Concordo con sepp2k, ma ci sono alcuni altri dettagli che potrebbero importa:

new HashSet<Foo>(myList); 

vi darà un set non ordinato che non ha i duplicati. In questo caso, la duplicazione viene identificata utilizzando il metodo .equals() sugli oggetti. Questo viene fatto in combinazione con il metodo .hashCode(). (Per maggiori sulla parità guardare here)

Un'alternativa che dà un insieme ordinato è:

new TreeSet<Foo>(myList); 

Questo funziona se Foo implementa Comparable. Se non, allora si può decidere di utilizzare un comparatore:

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

Questo dipende sia compareTo() (dall'interfaccia comparabili) o confrontare() (dal comparatore) per garantire l'unicità. Quindi, se ti interessa solo l'unicità, usa HashSet. Se si sta dopo l'ordinamento, considerare TreeSet. (Ricorda: Ottimizza in seguito!) Se l'efficienza nel tempo conta utilizzare un HashSet se l'efficienza dello spazio è importante, guarda TreeSet. Si noti che implementazioni più efficienti di Set e Map sono disponibili tramite Trove (e altre posizioni).

58

Se si utilizza la libreria Guava:

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

o meglio:

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

+1 per l'uso di ImmutableSet – tomrozb

+1

Perché ImmutableSet.copyOf è migliore? – user672009

+1

Quali vantaggi ha il nuovo HashSet() di Guava rispetto alla base di Java nuovo HashSet()? –

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

o completa esempio

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 per un esempio di codice completo. Una nota aggiuntiva qui è che l'hashing non è garantito per essere uguale da run to run. Ciò significa che la lista stampata dopo "Imposta valori ....." potrebbe essere "ABC" una corsa e "CBA" un'altra corsa. Come ho menzionato nella mia risposta, è possibile utilizzare un set di alberi per ottenere un ordine stabile. Un'altra opzione sarebbe quella di utilizzare un LinkedHashSet che ricorda l'ordine in cui gli oggetti sono stati aggiunti ad esso. – Spina

9

vorrei effettuare un controllo Null prima della conversione impostare .

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

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

5

È possibile convertire List<> a 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

Penso che volevi lanciarlo da List a Set. – Simon

17

utilizzando Java 8 è possibile utilizzare flusso:

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

Hai controllato la penalità delle prestazioni su questo? questo farebbe un iteratore iterabile, un nuovo HashSet(), e quindi per ogni voce di elenco, una chiamata addAll() sul nuovo set. Nel complesso, cca. 5 oggetti creati per qualcosa di semplice come un nuovo HashSet (lista). –

2

Ci sono vari modi per ottenere un Set come:

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

Quando usiamo Collectors.toSet() restituisce un set e come per il doc: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Se vogliamo ottenere un HashSet allora possiamo usare l'altra alternativa per ottenere un set (controllare set3).

3

Per Java 8 è molto facile:

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

Non dimentichiamo il nostro relativamente nuovo amico, flusso API. Se avete bisogno di lista pre-elaborazione prima di convertirlo in un set, è meglio avere qualcosa di simile:

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

Un altro Java 8 soluzione resiliente con Optional.ofNullable

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

con Java 10, si potrebbe ora utilizzare Set#copyOf per convertire facilmente un List<E> a un immodificabile Set<E>:

Esempio:

var set = Set.copyOf(list); 

Tenete a mente che si tratta di un'operazione non ordinata, e null elementi sono non consentito, in quanto sarà gettare un NullPointerException.

Se si desidera che sia modificabile, è sufficiente passarlo nel costruttore un'implementazione Set.

Problemi correlati