Le moyen le plus simple de convertir une liste en un ensemble en Java

628

Quelle est la façon la plus simple de convertir Listun Seten Java?

OHHAI
la source

Réponses:

1065
Set<Foo> foo = new HashSet<Foo>(myList);
sepp2k
la source
3
Bien que correcte, cette réponse manque de contexte technique suffisant pour justifier d'être la meilleure réponse / acceptée, car il y a des écueils ici selon l'implémentation de Setet Mapcelle qui est utilisée; HashSetest supposé ici.
Madbreaks
145

Je suis d'accord avec sepp2k, mais il y a d'autres détails qui pourraient être importants:

new HashSet<Foo>(myList);

vous donnera un ensemble non trié qui n'a pas de doublons. Dans ce cas, la duplication est identifiée à l'aide de la méthode .equals () sur vos objets. Cela se fait en combinaison avec la méthode .hashCode (). (Pour en savoir plus sur l'égalité, regardez ici )

Une alternative qui donne un ensemble trié est:

new TreeSet<Foo>(myList);

Cela fonctionne si Foo implémente Comparable. Si ce n'est pas le cas, vous pouvez utiliser un comparateur:

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

Cela dépend de compareTo () (à partir de l'interface comparable) ou compare () (à partir du comparateur) pour garantir l'unicité. Donc, si vous vous souciez uniquement de l'unicité, utilisez le HashSet. Si vous êtes après le tri, pensez au TreeSet. (N'oubliez pas: optimisez plus tard!) Si l'efficacité du temps compte, utilisez un HashSet si l'efficacité de l'espace est importante, regardez TreeSet. Notez que des implémentations plus efficaces de Set et Map sont disponibles via Trove (et d'autres emplacements).

Spina
la source
Merci d'avoir inclus le cas d'utilisation du comparateur personnalisé!
Justin Papez
70

Si vous utilisez la bibliothèque Guava :

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

ou mieux:

Set<Foo> set = ImmutableSet.copyOf(list);
Vitalii Fedorenko
la source
2
Pourquoi est-ce que ImmutableSet.copyOf est meilleur?
user672009
1
Quels sont les avantages de newHashSet () de Guava par rapport au nouveau HashSet () de base de Java?
Nelda.techspiress
@ Nelda.techspiress Le javadoc explique quand la méthode doit ou ne doit pas être utilisée. Notez la dernière partie: cette méthode n'est pas très utile et sera probablement déconseillée à l'avenir. Bien que je sois un peu surpris, la cohérence n'est pas mentionnée comme un facteur, comme c'est le cas ImmutableSet.of()par exemple. EDIT: ce n'est peut-être pas un facteur car toutes les surcharges sont inutiles.
shmosel
1
Hé merci pour la référence @shmosel, mais je cherchais plutôt des connaissances empiriques. Pour ceux qui ont utilisé la goyave, pourquoi la goyave serait-elle choisie plutôt que HashSet?
Nelda.techspiress
27

En utilisant java 8, vous pouvez utiliser stream:

List<Integer> mylist = Arrays.asList(100, 101, 102);
Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));
JimB
la source
10
Avez-vous vérifié la pénalité de performance à ce sujet? cela ferait un itérateur + itérable, un nouveau HashSet (), puis pour chaque élément de la liste, un appel addAll () sur le nouvel ensemble. Dans l'ensemble, cca. 5 objets créés pour quelque chose d'aussi simple qu'un nouveau HashSet (liste).
Agoston Horvath
1
@AgostonHorvath Merci pour votre commentaire. À l'origine, je cherchais ces informations lorsque je suis arrivé ici.
TheRealChx101
17
Set<E> alphaSet  = new HashSet<E>(<your List>);

ou exemple complet

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);
        }
    }
}
Sandeep Bhardwaj
la source
1
+1 pour un exemple de code complet. Une note supplémentaire ici est que le hachage n'est pas garanti d'être le même d'une exécution à l'autre. Cela signifie que la liste imprimée après «Définir les valeurs ...» pourrait être «ABC» un cycle et «CBA» un autre cycle. Comme je l'ai mentionné dans ma réponse, vous pouvez utiliser un ensemble d'arbres pour obtenir un ordre stable. Une autre option serait d'utiliser un LinkedHashSet qui se souvient de l'ordre dans lequel les éléments y ont été ajoutés.
Spina
8

Je voudrais effectuer une vérification Null avant de convertir en set.

if(myList != null){
Set<Foo> foo = new HashSet<Foo>(myList);
}
Ashish
la source
3
OuSet<Foo> foo = myList == null ? Collections.emptySet() : new HashSet<Foo>(myList);
vegemite4me
6

Vous pouvez convertir List<>enSet<>

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);
}
savanibharat
la source
Je pense que vous vouliez le lancer de List to Set.
Simon
6

Pour Java 8, c'est très simple:

List < UserEntity > vList= new ArrayList<>(); 
vList= service(...);
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet());
BERGUIGA Mohamed Amine
la source
"Real" Java 8 serait à utiliser new ArrayList<>();-)
JR
6

Java - addAll

set.addAll(aList);

Java - nouvel objet

new HashSet(list)

Java-8

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

Utiliser Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);
Ramesh Papaganti
la source
5

N'oublions pas notre ami relativement nouveau, API de diffusion. Si vous avez besoin de prétraiter la liste avant de la convertir en un ensemble, il est préférable d'avoir quelque chose comme:

list.stream().<here goes some preprocessing>.collect(Collectors.toSet());
shabunc
la source
4

La meilleure façon d'utiliser le constructeur

Set s= new HashSet(list);

Dans java 8, vous pouvez également utiliser le flux api ::

Set s= list.stream().collect(Collectors.toSet());
Nirbhay Rana
la source
3

Il existe différentes façons d'obtenir 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);

Lorsque nous utilisons Collectors.toSet()renvoie un ensemble et selon la doc: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Si nous voulons en obtenir un, HashSetnous pouvons utiliser l'autre alternative pour obtenir un ensemble (vérifier set3).

akhil_mittal
la source
3

Avec Java 10, vous pouvez désormais utiliser Set#copyOfpour convertir facilement un List<E>en un non modifiable Set<E>:

Exemple:

var set = Set.copyOf(list);

Gardez à l'esprit qu'il s'agit d'une opération non ordonnée et que les nulléléments ne sont pas autorisés, car cela entraînera un NullPointerException.

Si vous souhaitez qu'il soit modifiable, passez-le simplement au constructeur une Setimplémentation.

Jacob G.
la source
2

Une solution plus résiliente Java 8 avec Optional.ofNullable

Set<Foo> mySet = Optional.ofNullable(myList).map(HashSet::new).orElse(null);
Shenal Silva
la source
2

Si vous utilisez les collections Eclipse :

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

L' MutableSetinterface s'étend java.util.Setalors que l' MutableIntSetinterface ne le fait pas. Vous pouvez également convertir n'importe quel fichier Iterableen Setutilisant la Setsclasse d'usine.

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

Il y a plus d'explications sur les usines modifiables disponibles dans les collections Eclipse ici .

Si vous voulez un ImmutableSetde a List, vous pouvez utiliser l' Setsusine comme suit:

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

Remarque: je suis un committer pour les collections Eclipse

Donald Raab
la source
0

N'oubliez pas que la conversion de List en Set supprimera les doublons de la collection car List prend en charge les doublons mais Set ne prend pas en charge les doublons en Java.

Conversion directe: la façon la plus courante et la plus simple de convertir une liste en un ensemble

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

Collections Apache Commons: Vous pouvez également utiliser l'API Commons Collections pour convertir une liste en un ensemble: -

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

Utiliser Stream: Une autre façon est de convertir une liste donnée en flux, puis de diffuser pour définir: -

// 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()); 
Abdul Alim Shakir
la source