Il modo più semplice per convertire un elenco in un set in Java


628

Qual è il modo più semplice per convertire a Listin Setin Java?

Risposte:


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

3
Mentre corretta questa risposta manca di sufficiente contesto tecnico per giustificare la risposta migliore / accettata, perché ci sono insidie ​​qui a seconda di quali implementazioni di Sete Mapsi sta usando; HashSetè assunto qui.
Madbreaks,

145

Sono d'accordo con sepp2k, ma ci sono altri dettagli che potrebbero interessare:

new HashSet<Foo>(myList);

ti darà un set non ordinato che non ha duplicati. In questo caso, la duplicazione viene identificata usando il metodo .equals () sui tuoi oggetti. Questo viene fatto in combinazione con il metodo .hashCode (). (Per ulteriori informazioni sull'uguaglianza, guarda qui )

Un'alternativa che fornisce un set ordinato è:

new TreeSet<Foo>(myList);

Questo funziona se Foo implementa Comparable. In caso contrario, potresti voler utilizzare un comparatore:

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

Questo dipende da compareTo () (dall'interfaccia comparabile) o compare () (dal comparatore) per garantire l'univocità. Quindi, se ti interessa solo l'unicità, usa HashSet. Se dopo l'ordinamento, considera TreeSet. (Ricorda: ottimizza in seguito!) Se l'efficienza nel tempo conta, usa un HashSet se l'efficienza dello spazio è importante, guarda TreeSet. Si noti che implementazioni più efficienti di Set e Mappa sono disponibili tramite Trove (e altre località).


Grazie per aver incluso il caso d'uso del comparatore personalizzato!
Justin Papez,

70

Se usi la libreria Guava :

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

o meglio:

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

2
Perché ImmutableSet.copyOf è meglio?
user672009,

1
Quali sono i vantaggi di newHashSet () di Guava rispetto al nuovo HashSet () di Java di base?
Nelda.techspiress,

@ Nelda.techspiress Il javadoc discute quando il metodo dovrebbe o non dovrebbe essere usato. Nota la parte finale: questo metodo non è molto utile e probabilmente sarà deprecato in futuro. Anche se sono un po 'sorpreso, la coerenza non è menzionata come un fattore, come lo è ImmutableSet.of()per esempio. EDIT: potrebbe non essere un fattore perché tutti i sovraccarichi non sono necessari.
shmosel,

1
Ehi, grazie per il riferimento @shmosel, ma stavo cercando più informazioni empiriche. Per coloro che hanno usato Guava, perché Guava dovrebbe essere scelto su HashSet?
Nelda.techspiress,

27

Usando java 8 puoi usare stream:

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

10
Hai verificato la penalità prestazionale su questo? questo farebbe un iterabile + iteratore, 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 (elenco).
Agoston Horvath,

1
@AgostonHorvath Grazie per il tuo commento. Inizialmente stavo cercando queste informazioni quando sono venuto qui.
TheRealChx101,

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

o esempio completo

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'hash non è garantito essere lo stesso da una corsa all'altra. Ciò significa che l'elenco stampato dopo 'Imposta valori .....' potrebbe essere 'ABC' una corsa e 'CBA' un'altra corsa. Come ho detto nella mia risposta, è possibile utilizzare un set di alberi per ottenere un ordinamento stabile. Un'altra opzione sarebbe quella di utilizzare un LinkedHashSet che ricorda l'ordine in cui gli articoli sono stati aggiunti.
Spina,

8

Esegui un controllo Null prima di convertirlo in set.

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

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

6

È possibile convertire List<>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);
}

Penso che volevi dire lanciarlo da Elenco a Set.
Simon,

6

Per Java 8 è molto semplice:

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

Java "reale" sarebbe da usare new ArrayList<>();-)
JR

6

Java - addAll

set.addAll(aList);

Java - nuovo oggetto

new HashSet(list)

Java-8

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

Usando Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

Non dimentichiamo il nostro amico relativamente nuovo, API stream. Se devi preelaborare l'elenco prima di convertirlo in un set, è meglio avere qualcosa di simile:

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

4

Il modo migliore per usare il costruttore

Set s= new HashSet(list);

In java 8 puoi anche usare stream api ::

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

3

Esistono vari modi per ottenere un Setas:

    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 HashSetallora possiamo usare l'altra alternativa per ottenere un set (spunta set3).


3

Con Java 10, ora puoi usare Set#copyOfper convertire facilmente un List<E>in non modificabile Set<E>:

Esempio:

var set = Set.copyOf(list);

Tieni presente che si tratta di un'operazione non ordinata e che gli nullelementi non sono consentiti, in quanto genererà a NullPointerException.

Se desideri che sia modificabile, passa semplicemente nel costruttore Setun'implementazione.


2

Una soluzione resiliente più Java 8 con Optional.ofNullable

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

2

Se si utilizzano le raccolte Eclipse :

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

L' MutableSetinterfaccia si estende java.util.Setmentre l' MutableIntSetinterfaccia no. Puoi anche convertire qualsiasi Iterablein a Setusando la Setsclasse factory.

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

C'è più spiegazione delle fabbriche mutabili disponibili nelle Collezioni Eclipse qui .

Se si desidera un ImmutableSetda a List, è possibile utilizzare la Setsfabbrica come segue:

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

Nota: sono un committer per le raccolte Eclipse


0

Ricorda che, la conversione da Elenco a Set rimuoverà i duplicati dalla raccolta perché Elenco supporta i duplicati ma Set non supporta i duplicati in Java.

Conversione diretta: il modo più comune e semplice per convertire un elenco in un set

// 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 Collections: puoi anche utilizzare l'API Commons Collections per convertire un elenco in un set: -

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

Utilizzo di Stream: un altro modo è convertire un determinato elenco in streaming, quindi eseguire lo streaming per impostare: -

// 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()); 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.