Las listas en Java son conjuntos ordenados de datos, mientras que los conjuntos son conjuntos desordenados. Una lista puede tener entradas duplicadas, un conjunto no. Ambas estructuras de datos son útiles en diferentes situaciones.
Es útil saber cómo convertir un conjunto en una lista. Permite convertir datos desordenados en datos ordenados.
Inicializando un conjunto
Inicialicemos un conjunto y agreguemosle algunos elementos.
import java.util.*;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); System.out.println(a); }}
El método add() de HashSet agrega los elementos al conjunto. Tenga en cuenta que los elementos son distintos. No hay forma de obtener los elementos según su orden de inserción, ya que los conjuntos no están ordenados.
Convertir un conjunto en una lista en Java
Convirtamos el conjunto en una lista. Hay varias formas de hacerlo. Cada una es diferente de la otra y estas diferencias son sutiles.
1. Constructor de listas con argumento de conjunto
La forma más sencilla de convertir un conjunto en una lista es pasar el conjunto como argumento al crear la lista. Esto llama al constructor y, a partir de ahí, el constructor se encarga del resto.
import java.util.*;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr = new ArrayList(a); System.out.println(arr); System.out.println(arr.get(1)); }}
Como el conjunto se ha convertido en una lista, los elementos ahora están ordenados. Eso significa que podemos usar el método get() para acceder a los elementos por índice.
2. Uso del bucle for convencional
Podemos utilizar el viejo bucle for para copiar explícitamente los elementos del conjunto a la lista.
import java.util.*;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr = new ArrayList(a); for (int i : a) arr.add(i); System.out.println(arr); System.out.println(arr.get(1)); } }
El bucle for recorre el conjunto elemento por elemento y agrega los elementos a la lista.
3. Método addAll() de la lista
Las listas tienen un método llamado addAll() que agrega varios valores a la lista a la vez. Es posible que recuerdes esta operación por su uso para fusionar dos listas. addAll() también funciona para agregar los elementos de un conjunto a una lista.
import java.util.*;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr = new ArrayList(); arr.addAll(a); System.out.println(arr); System.out.println(arr.get(1)); }}
4. Método collect() de la API de transmisión
Stream.collect() está disponible a partir de Java 8. El recopilador ToList recopila todos los elementos de Stream en una instancia de List.
import java.util.*;import java.util.stream.Collectors;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr; arr = a.stream().collect(Collectors.toList()); System.out.println(arr); System.out.println(arr.get(1)); }}
La documentación de stream.collect() menciona que no hay garantía sobre el tipo, la mutabilidad, la serialización o la seguridad de subprocesos de la lista devuelta. Si se requiere más control sobre la lista devuelta, utilice toCollection(Supplier).
Para especificar el tipo de lista, utilice toCollection(ArrayList::new)
import java.util.*;import java.util.stream.Collectors;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr; arr = a.stream().collect(Collectors.toCollection(ArrayList::new)); System.out.println(arr); System.out.println(arr.get(1)); }}
Lectura recomendada : Streams en Java
5. Método List.copyOf()
A partir de Java 10, List tiene un método copyOf() . El método devuelve una lista no modificable que contiene los elementos de la colección dada, en su orden de iteración. La lista no puede contener ningún elemento nulo. En caso de que el conjunto contenga ‘null’, el método devuelve una excepción de puntero nulo.
import java.util.*;import java.util.stream.Collectors;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); ListInteger arr; arr = List.copyOf(a); System.out.println(arr); System.out.println(arr.get(1)); }}
Agregar un valor nulo en el conjunto e intentar convertirlo en una lista:
import java.util.*;import java.util.stream.Collectors;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); a.add(null); ListInteger arr; arr = List.copyOf(a); System.out.println(arr); System.out.println(arr.get(1)); }}
Si intenta agregar un elemento a una lista inmutable, obtendrá un error similar al siguiente.
Usando el método addAll() para convertir un conjunto con elementos nulos en una lista:
import java.util.*;import java.util.stream.Collectors;public class Main { public static void main(String[] args) { SetInteger a = new HashSet(); a.add(1); a.add(2); a.add(3); a.add(1); a.add(null); ListInteger arr = new ArrayList(); arr.addAll(a); // arr = List.copyOf(a); System.out.println(arr); System.out.println(arr.get(1)); }}
Tenga en cuenta que el valor nulo aparece al principio de la lista.
Conclusión
Vimos algunos métodos realmente interesantes para convertir un conjunto en una lista. Es importante prestar atención al tipo de lista que se crea a partir de cada método. Por ejemplo, el método copyOf() produce una lista inmutable y no puede manejar elementos nulos, mientras que stream.collect() no garantiza nada. Constructor y addAll() son los más confiables del grupo.