Convertir matriz a lista en Java

1028

¿Cómo convierto una matriz en una lista en Java?

Usé el Arrays.asList()pero el comportamiento (y la firma) de alguna manera cambió de Java SE 1.4.2 (documentos ahora en el archivo) a 8 y la mayoría de los fragmentos que encontré en la web usan el comportamiento 1.4.2.

Por ejemplo:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • en 1.4.2 devuelve una lista que contiene los elementos 1, 2, 3
  • en 1.5.0+ devuelve una lista que contiene la matriz de spam

En muchos casos, debería ser fácil de detectar, pero a veces puede pasar desapercibido:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);
Alexandru
fuente
20
Creo que su ejemplo está roto Arrays.asList(new int[] { 1, 2, 3 }):; definitivamente no compiló en Java 1.4.2, porque un noint[] es un . Object[]
Joachim Sauer el
1
Oh, puede que tengas razón. No tenía el compilador Java 1.4.2 para probar mi ejemplo antes de publicar. Ahora, después de tu comentario y la respuesta de Joe, todo tiene mucho más sentido.
Alexandru
1
Pensé que Autoboxing habría cubierto la conversión de primitiva a la clase entera de contenedor. Puede hacer el lanzamiento usted mismo primero y luego el código anterior Arrays.asListdebería funcionar.
Horse Voice
2
Stream.boxed () de Java 8 se encargará del autoboxing y puede usarse para esto. Vea mi respuesta a continuación .
Ibrahim Arief
Solución Java 8: stackoverflow.com/questions/2607289/…
akhil_mittal

Respuestas:

1431

En su ejemplo, es porque no puede tener una Lista de un tipo primitivo. En otras palabras, List<int>no es posible.

Sin embargo, puede List<Integer>usar la Integerclase que envuelve la intprimitiva. Convierta su matriz a a Listcon el Arrays.asListmétodo de utilidad.

Integer[] spam = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(spam);

Vea este código en vivo en IdeOne.com .

Joe Daley
fuente
112
O incluso más simple: Arrays.asList (1, 2, 3);
Kong
45
¿Cómo sabe no crear un List<Integer[]>?
Thomas Ahle
25
Falla en Java 5+.
djechlin
66
@ThomasAhle No crea una Lista <Integer []> crea un objeto List <Integer>. Y si quiere estar seguro de escribir, escriba: Arrays. <Integer> asList (spam);
user1712376
66
@ThomasAhle Esa es una buena pregunta. Supongo que es solo una regla en el compilador de Java. Por ejemplo, el siguiente código devuelve una Lista <Entero []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon
167

En Java 8, puede usar transmisiones:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());
Ibrahim Arief
fuente
Esto es bueno, pero no funcionará boolean[]. Supongo que es porque es igual de fácil hacer un Boolean[]. Esa es probablemente una mejor solución. De todos modos, es una peculiaridad interesante.
GlenPeterson
138

Hablando sobre la forma de conversión, depende de por qué necesita su List. Si lo necesita solo para leer datos. OK aquí tienes:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);

Pero luego, si haces algo como esto:

list.add(1);

se obtiene java.lang.UnsupportedOperationException. Entonces, en algunos casos, incluso necesitas esto:

Integer[] values = { 1, 3, 7 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));

El primer enfoque en realidad no convierte la matriz, sino que la 'representa' como a List. Pero la matriz está bajo el capó con todas sus propiedades, como un número fijo de elementos. Tenga en cuenta que necesita especificar el tipo al construir ArrayList.

Roman Nikitchenko
fuente
1
"inmutabilidad" me confundió por un momento. Obviamente, puede cambiar los valores de la matriz. Sin embargo, no puede cambiar su tamaño.
Tim Pohlmann
125

El problema es que los varargs se introdujeron en Java5 y, desafortunadamente, también Arrays.asList()se sobrecargaron con una versión vararg. Así Arrays.asList(spam)lo entiende el compilador Java5 como un parámetro vararg de matrices int

Este problema se explica con más detalles en Effective Java 2nd Ed., Capítulo 7, Elemento 42.

Péter Török
fuente
44
Entiendo lo que sucedió, pero no por qué no está documentado. Estoy buscando una solución alternativa sin volver a implementar la rueda.
Alexandru
2
@UsmanIsmail A partir de Java 8, podemos usar secuencias para esta conversión. Vea mi respuesta a continuación .
Ibrahim Arief
109

Parece un poco tarde, pero aquí están mis dos centavos. No podemos tener List<int>como intes un tipo primitivo, por lo que solo podemos tener List<Integer>.

Java 8 (int array)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 

Java 8 y menos (matriz entera)

Integer[] integers = new Integer[] {1,2,3,4,5};
List<Integer> list21 =  Arrays.asList(integers); // returns a fixed-size list backed by the specified array.
List<Integer> list22 = new ArrayList<>(Arrays.asList(integers)); // good
List<Integer> list23 = Arrays.stream(integers).collect(Collectors.toList()); //Java 8 only

¿Necesita ArrayList y no List?

En caso de que queramos una implementación específica de, Listpor ejemplo ArrayList, podemos usar toCollectioncomo:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

¿Por qué list21no se puede modificar estructuralmente?

Cuando usamos Arrays.asListel tamaño de la lista devuelta es fijo porque la lista devuelta no lo es java.util.ArrayList, sino una clase estática privada definida en su interior java.util.Arrays. Entonces, si agregamos o eliminamos elementos de la lista devuelta, se UnsupportedOperationExceptionarrojará un . Entonces deberíamos ir list22cuando queramos modificar la lista. Si tenemos Java8, entonces también podemos ir con list23.

Para que quede claro, list21puede modificarse en el sentido de que podemos llamar, list21.set(index,element)pero esta lista puede no modificarse estructuralmente, es decir, no puede agregar o eliminar elementos de la lista. También puedes consultar esta pregunta .


Si queremos una lista inmutable, podemos envolverla como:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));

Otro punto a tener en cuenta es que el método Collections.unmodifiableListdevuelve una vista no modificable de la lista especificada. Una colección de vistas no modificables es una colección que no se puede modificar y también es una vista de una colección de respaldo. Tenga en cuenta que los cambios en la colección de respaldo aún podrían ser posibles, y si ocurren, son visibles a través de la vista no modificable.

Podemos tener una lista verdaderamente inmutable en Java 9 y 10.

Lista verdaderamente inmutable

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

Java 10 (lista verdaderamente inmutable) de dos maneras:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

También revise esta respuesta mía para más.

akhil_mittal
fuente
@BasilBourque que quise decir no puede modificar la estructura de la lista por adición / eliminación, pero puede cambiar los elementos.
akhil_mittal
De hecho, probé un código y confirmé que llamar List::addy List::removefalla con una lista devuelta por Arrays.asList. El JavaDoc para ese método está mal escrito y no está claro en este punto. En mi tercera lectura, supongo que la frase "tamaño fijo" estaba destinada a decir que uno no puede agregar o eliminar elementos.
Basil Bourque
12

Aún más corto:

List<Integer> list = Arrays.asList(1, 2, 3, 4);
Vitaliy Sokolov
fuente
11

Recientemente tuve que convertir una matriz en una Lista. Más tarde, el programa filtró la lista intentando eliminar los datos. Cuando utiliza la función Arrays.asList (matriz), crea una colección de tamaño fijo: no puede agregar ni eliminar. Esta entrada explica el problema mejor de lo que puedo: ¿Por qué obtengo una UnsupportedOperationException cuando intento eliminar un elemento de una Lista? .

Al final, tuve que hacer una conversión "manual":

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

Supongo que podría haber agregado la conversión de una matriz a una lista utilizando una operación List.addAll (elementos).

Steve Gelman
fuente
11
new ArrayList<ListItem>(Arrays.asList(itemsArray))haría lo mismo
Marco13
1
@BradyZhu: Concedido, la respuesta anterior no resuelve mi problema con la matriz de tamaño fijo, pero básicamente estás diciendo RTFM aquí, que siempre es una mala forma. Explique qué hay de malo en la respuesta o no se moleste en comentar.
Steve Gelman
2
Las herramientas de inspección pueden mostrar una advertencia aquí, y usted ha nombrado la razón. No es necesario copiar los elementos manualmente, en su Collections.addAll(items, itemsArray)lugar , úselos.
Darek Kay
Solo dale a esta excepción. Me temo que la respuesta de Marco13 debería ser la respuesta correcta. Puede que tenga que ir a través del código de todo el año para corregir todas las excepciones "asList".
7

Usar matrices

Esta es la forma más simple de convertir una matriz List. Sin embargo, si intenta agregar un nuevo elemento o eliminar un elemento existente de la lista, se UnsupportedOperationExceptiongenerará un .

Integer[] existingArray = {1, 2, 3};
List<Integer> list1 = Arrays.asList(existingArray);
List<Integer> list2 = Arrays.asList(1, 2, 3);

// WARNING:
list2.add(1);     // Unsupported operation!
list2.remove(1);  // Unsupported operation!

Uso de ArrayList u otras implementaciones de listas

Puede usar un forbucle para agregar todos los elementos de la matriz a una Listimplementación, por ejemplo ArrayList:

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}

Usando Stream API en Java 8

Puede convertir la matriz en una secuencia y luego recopilarla utilizando diferentes recopiladores: el recopilador predeterminado en Java 8 se usa ArrayListdetrás de la pantalla, pero también puede imponer su implementación preferida.

List<Integer> list1, list2, list3;
list1 = Stream.of(1, 2, 3).collect(Collectors.toList());
list2 = Stream.of(1, 2, 3).collect(Collectors.toCollection(ArrayList::new));
list3 = Stream.of(1, 2, 3).collect(Collectors.toCollection(LinkedList::new));

Ver también:

Mincong Huang
fuente
6

Otra solución alternativa si usa apache commons-lang:

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(ArrayUtils.toObject(spam));

Donde ArrayUtils.toObject convierte int[]aInteger[]

Alaska
fuente
5

tienes que echar en matriz

Arrays.asList((Object[]) array)
Giancarlo Frison
fuente
3
java: tipos incompatibles: int [] no se puede convertir a java.lang.Object []
dVaffection el
@dVaffection Luego se envía a int []. Parte importante es emitir a una matriz.
Nebril
5

Un trazador de líneas:

List<Integer> list = Arrays.asList(new Integer[] {1, 2, 3, 4});
Bhushan
fuente
5

Si está apuntando a Java 8 (o posterior), puede intentar esto:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());

NOTA:

Presta atención al Collectors.<Integer>toList(), este método genérico te ayuda a evitar el error "No coinciden los tipos: no se puede convertir de List<Object>a List<Integer>".

nybon
fuente
4
  1. Usando guayaba:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. Usando las colecciones de Apache Commons:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);
Danail Tsvetanov
fuente
3

Si esto ayuda: he tenido el mismo problema y simplemente escribí una función genérica que toma una matriz y devuelve una ArrayList del mismo tipo con el mismo contenido:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}
kleines filmröllchen
fuente
¿Qué pasa si no ayuda? Entonces que hiciste ?? ... jk :)
Sᴀᴍ Elᴇᴌᴀ
2

Matriz dada:

    int[] givenArray = {2,2,3,3,4,5};

Conversión de matriz entera a Lista entera

Una forma: boxed () -> devuelve IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

Segunda forma: mapear cada elemento de la secuencia a Integer y luego recopilar

NOTA: Usando mapToObj puede convertir cada elemento int en secuencia de cadena, secuencia de caracteres, etc., colocando i en (char) i

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

Conversión de un tipo de matriz a otro tipo Ejemplo:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());
Arpan Saini
fuente
1

Por lo tanto, depende de la versión de Java que esté intentando.

Java 7

 Arrays.asList(1, 2, 3);

O

       final String arr[] = new String[] { "G", "E", "E", "K" };
       final List<String> initialList = new ArrayList<String>() {{
           add("C");
           add("O");
           add("D");
           add("I");
           add("N");
       }};

       // Elements of the array are appended at the end
       Collections.addAll(initialList, arr);

O

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

En Java 8

int[] num = new int[] {1, 2, 3};
List<Integer> list = Arrays.stream(num)
                        .boxed().collect(Collectors.<Integer>toList())

Referencia : http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/

Hitesh Garg
fuente
1

¿Puede mejorar esta respuesta, por favor? Esto es lo que uso, pero no estoy 100% claro. Funciona bien pero intelliJ agregó una nueva WeatherStation [0]. ¿Por qué el 0?

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }

DevilCode
fuente
¿Por qué hemos de mejorar su pregunta? O sabes la respuesta, o no. Por supuesto, debe proporcionar una respuesta que realmente ayude a los demás, no una que confunda más de lo que ayuda.
HimBromBeere
-2

use dos líneas de código para convertir la matriz a la lista si la usa en un valor entero, debe usar el tipo de autoboxing para el tipo de datos primitivo

  Integer [] arr={1,2};
  Arrays.asList(arr);
yousef
fuente