La forma más fácil de convertir una lista en un conjunto en Java

Respuestas:

1065
Set<Foo> foo = new HashSet<Foo>(myList);
sepp2k
fuente
3
Si bien es correcta, esta respuesta carece de un contexto técnico suficiente para garantizar que sea la respuesta mejor / aceptada, porque aquí existen dificultades dependiendo de qué implementaciones se estén usando Sety cuáles se estén Maputilizando; HashSetse asume aquí.
Madbreaks
145

Estoy de acuerdo con sepp2k, pero hay otros detalles que pueden ser importantes:

new HashSet<Foo>(myList);

le dará un conjunto sin clasificar que no tiene duplicados. En este caso, la duplicación se identifica utilizando el método .equals () en sus objetos. Esto se realiza en combinación con el método .hashCode (). (Para más información sobre igualdad, mira aquí )

Una alternativa que da un conjunto ordenado es:

new TreeSet<Foo>(myList);

Esto funciona si Foo implementa Comparable. Si no es así, es posible que desee utilizar un comparador:

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

Esto depende de compareTo () (desde la interfaz comparable) o compare () (desde el comparador) para garantizar la unicidad. Entonces, si solo te importa la singularidad, usa el HashSet. Si buscas ordenar, considera el TreeSet. (Recuerde: ¡Optimice más tarde!) Si la eficiencia del tiempo es importante, use un HashSet si la eficiencia del espacio es importante, mire TreeSet. Tenga en cuenta que las implementaciones más eficientes de Set y Map están disponibles a través de Trove (y otras ubicaciones).

Espina
fuente
¡Gracias por incluir el caso de uso de Comparator personalizado!
Justin Papez
70

Si usa la biblioteca Guava :

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

o mejor:

Set<Foo> set = ImmutableSet.copyOf(list);
Vitalii Fedorenko
fuente
2
¿Por qué es mejor ImmutableSet.copyOf?
user672009
1
¿Qué ventajas tiene el nuevo HashSet () de Guava sobre el nuevo HashSet () básico de Java?
Nelda.techspiress
@ Nelda.techspiress El javadoc analiza cuándo se debe usar o no el método. Tenga en cuenta la parte final: este método no es muy útil y probablemente quedará obsoleto en el futuro. Aunque estoy un poco sorprendido, la consistencia no se menciona como un factor, como lo es ImmutableSet.of(), por ejemplo. EDITAR: puede no ser factor porque todas las sobrecargas son innecesarias.
shmosel
1
Hola, gracias por la referencia @shmosel, pero estaba buscando más conocimiento empírico. Para aquellos que han usado Guava, ¿por qué se elegiría Guava sobre HashSet?
Nelda.techspiress
27

Usando java 8 puedes usar stream:

List<Integer> mylist = Arrays.asList(100, 101, 102);
Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));
JimB
fuente
10
¿Has comprobado la penalización de rendimiento en esto? esto haría un iterador + iterable, un nuevo HashSet (), y luego para cada elemento de la lista, una llamada addAll () en el nuevo conjunto. En general, cca. 5 objetos creados para algo tan simple como un nuevo HashSet (lista).
Agoston Horvath
1
@AgostonHorvath Gracias por tu comentario. Originalmente estaba buscando esa información cuando vine aquí.
TheRealChx101
17
Set<E> alphaSet  = new HashSet<E>(<your List>);

o ejemplo 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);
        }
    }
}
Sandeep Bhardwaj
fuente
1
+1 para un ejemplo de código completo. Una nota adicional aquí es que no se garantiza que el hashing sea el mismo de una ejecución a otra. Eso significa que la lista impresa después de 'Establecer valores .....' podría ser 'ABC' una ejecución y 'CBA' otra ejecución. Como mencioné en mi respuesta, podría usar un conjunto de árbol para obtener un orden estable. Otra opción sería utilizar un LinkedHashSet que recuerde el orden en que se le agregaron los elementos.
Espina
8

Realizaría una comprobación nula antes de convertir a set.

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

Puedes convertir List<>aSet<>

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
fuente
Creo que te referías a enviarlo de Lista a Conjunto.
Simon
6

Para Java 8 es muy fácil:

List < UserEntity > vList= new ArrayList<>(); 
vList= service(...);
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet());
BERGUIGA Mohamed Amine
fuente
"Real" Java 8 sería para usar new ArrayList<>();-)
JR
6

Java - addAll

set.addAll(aList);

Java - nuevo objeto

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);
Ramesh Papaganti
fuente
5

No olvidemos a nuestro amigo relativamente nuevo, Stream API. Si necesita preprocesar la lista antes de convertirla en un conjunto, es mejor tener algo como:

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

La mejor manera de usar constructor

Set s= new HashSet(list);

En java 8 también puedes usar stream api ::

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

Hay varias formas de obtener un Setcomo:

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

Cuando usamos Collectors.toSet()devuelve un conjunto y según el doc: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Si queremos obtener un, HashSetentonces podemos usar la otra alternativa para obtener un conjunto (verificar set3).

akhil_mittal
fuente
3

Con Java 10, ahora puede usar Set#copyOfpara convertir fácilmente un List<E>a no modificable Set<E>:

Ejemplo:

var set = Set.copyOf(list);

Tenga en cuenta que esta es una operación desordenada, y los nullelementos no están permitidos, ya que arrojará un NullPointerException.

Si desea que sea modificable, simplemente páselo al constructor una Setimplementación.

Jacob G.
fuente
2

Una solución más resistente de Java 8 con Optional.ofNullable

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

Si usa Eclipse Collections :

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

La MutableSetinterfaz se extiende java.util.Setmientras que la MutableIntSetinterfaz no. También puede convertir cualquiera Iterablea Setusar la Setsclase de fábrica.

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

Hay más explicaciones de las fábricas mutables disponibles en Eclipse Collections aquí .

Si desea un ImmutableSetde a List, puede usar la Setsfábrica de la siguiente manera:

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

Nota: Soy un committer para Eclipse Collections

Donald Raab
fuente
0

Recuerde que, la conversión de List a Set eliminará los duplicados de la colección porque List admite duplicados pero Set no admite duplicados en Java.

Conversión directa: la forma más común y sencilla de convertir una lista en un conjunto

// 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: también puede usar la API de Commons Collections para convertir una lista en un conjunto: -

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

Uso de Stream: Otra forma es convertir la lista dada a stream, luego stream para establecer: -

// 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
fuente