2009-09-15 19 views

Respuesta

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

Esto arrojará NullPointerException si la lista es nula – Ashish

+87

@Ashish: Esto es completamente irrelevante para la pregunta. Nadie preguntó cómo convertir null en un conjunto. Las personas que siempre necesitan manejar nulos son una señal de lo que es Java (cultura) rota. Casi siempre, null es un error. LANZAR UNA EXCEPCIÓN ES REALMENTE LO MEJOR QUE PUEDE HACER. Especialmente cuando se trata de una referencia nula a una Colección: ¿con qué frecuencia se puede imaginar un significado semántico de una referencia nula a una Colección, y tal que el significado es diferente de una Colección vacía? –

+2

De acuerdo, en lugar de nulo, debe (casi) pasar siempre: instancias vacías estáticas inmóviles de sus beans, o Collections.emptyXXX() para sus colecciones. También hace que su código sea mucho más fácil de leer si no está contaminado con null-checks al inicio de cada método. –

112

Estoy de acuerdo con sepp2k, pero hay algunos otros detalles que podría ser importante:

new HashSet<Foo>(myList); 

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

Una alternativa que da un conjunto ordenado es:

new TreeSet<Foo>(myList); 

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

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

Esto depende ya sea compareTo() (de la interfaz similar) o comparar() (del comparador) para garantizar la unicidad. Entonces, si solo te preocupa la singularidad, utiliza el HashSet. Si buscas una clasificación, considera el TreeSet. (Recuerde: ¡Optimice más tarde!) Si la eficiencia del tiempo es importante, utilice un HashSet si la eficiencia del espacio importa, consulte 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).

58

Si utiliza el Guava biblioteca:

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

, o mejor:

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

+1 para usar ImmutableSet – tomrozb

+1

¿Por qué ImmutableSet.copyOf es mejor? – user672009

+1

¿Qué ventajas tiene newHashSet de Guava() sobre el nuevo java HashSet()? –

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

o completa ejemplo

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 para obtener un ejemplo de código completo. Una nota adicional aquí es que no se garantiza que el hashing sea el mismo desde la ejecución hasta la ejecución. 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 árboles para obtener un orden estable. Otra opción sería usar un LinkedHashSet que recuerde el orden en que se agregaron los elementos. – Spina

9

Me gustaría realizar una comprobación nulo antes de la conversión para establecer .

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

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

5

Puede convertir 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

Creo que se refería a enviarlo de List a Set. – Simon

17

Utilización de Java 8 se puede utilizar la secuencia:

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

¿Ha comprobado la penalidad 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). –

2

Hay varias maneras de obtener un Set como:

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 documento: There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returned. Si queremos obtener un HashSet, podemos usar la otra alternativa para obtener un conjunto (marque set3).

3

Para Java 8 es muy fácil:

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

No olvidemos nuestra relativamente nuevo amigo, API corriente. Si necesita a la lista de preproceso antes de convertirlo en un conjunto, es mejor tener algo como:

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

A más de Java 8 solución flexible con Optional.ofNullable

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

Con Java 10, usted podría ahora utilizar Set#copyOf para convertir fácilmente un List<E> a un inmodificable Set<E>:

Ejemplo:

var set = Set.copyOf(list); 

Tenga en cuenta que esta es una operación no ordenada, y null elementos son no permitido, ya que arrojará un NullPointerException.

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

Cuestiones relacionadas