Crear ArrayList desde una matriz

3597

Tengo una matriz que se inicializa como:

Element[] array = {new Element(1), new Element(2), new Element(3)};

Me gustaría convertir esta matriz en un objeto de la ArrayListclase.

ArrayList<Element> arraylist = ???;
Ron Tuffin
fuente
50
En Java9 -> List <String> list = List.of ("Hola", "Mundo", "desde", "Java");
MarekM
18
@MarekM Esta respuesta es incorrecta, ya que no devuelve un ArrayList. El cartel pidió específicamente eso.
Dorian Gray
44
Creo que no minó usando la interfaz de Lista, porque es la mejor práctica. Pero si lo desea, aquí está: nueva ArrayList <> (List.of ("Hello", "World", "from", "Java"));
MarekM
10
El punto no se trata de usar la interfaz, el punto es que en su solución, la lista devuelta no se puede modificar. Eso podría ser más un problema, y ​​una razón por la que pidió una ArrayList
Dorian Gray

Respuestas:

4603
new ArrayList<>(Arrays.asList(array));
Tom
fuente
361
Sí. Y en el caso (más común) donde solo desea una lista, la new ArrayListllamada también es innecesaria.
Calum
143
@Luron - solo useList<ClassName> list = Arrays.asList(array)
Pool
248
@Calum y @Pool: como se indica a continuación en la respuesta de Alex Miller, usar Arrays.asList(array)sin pasarlo a un nuevo ArrayListobjeto arreglará el tamaño de la lista. Una de las razones más comunes para usar un ArrayListes poder cambiar dinámicamente su tamaño, y su sugerencia lo evitaría.
Code Jockey
130
Arrays.asList () es una función horrible, y nunca debe usar su valor de retorno tal como está. Rompe la plantilla de la Lista, así que úsela siempre en la forma indicada aquí, incluso si parece redundante. Buena respuesta.
Adam
83
@ Adam Por favor, estudie el javadoc para java.util.List. El contrato para agregar les permite lanzar una UnsupportedOperationException. docs.oracle.com/javase/7/docs/api/java/util/… Es cierto que desde una perspectiva orientada a objetos no es muy bueno que muchas veces tengas que conocer la implementación concreta para usar una colección: esto fue una elección de diseño pragmático para mantener el marco simple.
lbalazscs
918

Dado:

Element[] array = new Element[] { new Element(1), new Element(2), new Element(3) };

La respuesta más simple es hacer:

List<Element> list = Arrays.asList(array);

Esto funcionará bien. Pero algunas advertencias:

  1. La lista devuelta desde asList tiene un tamaño fijo . Por lo tanto, si desea poder agregar o eliminar elementos de la lista devuelta en su código, deberá envolverlo en una nueva ArrayList. De lo contrario obtendrás un UnsupportedOperationException.
  2. La lista devuelta desde asList()está respaldada por la matriz original. Si modifica la matriz original, la lista también se modificará. Esto puede ser sorprendente.
Alex Miller
fuente
66
¿Cuál es la complejidad temporal de ambas operaciones? Me refiero con y sin usar la construcción explícita de matrices.
condenado
35
Arrays.asList () simplemente crea una ArrayList envolviendo la matriz existente para que sea O (1).
Alex Miller
27
Ajustar en una nueva ArrayList () hará que todos los elementos de la lista de tamaño fijo se repitan y se agreguen a la nueva ArrayList, así que O (n).
Alex Miller
8
La implementación de List devuelta por asList () no implementa varios de los métodos de List (como add (), remove (), clear (), etc ...) que explica la excepción UnsupportedOperationException. definitivamente una advertencia ...
septiembre
8
Cuando la pregunta pide "un objeto de la clase ArrayList", creo que es razonable asumir que la clase a la que se refiere es java.util.ArrayList. Arrays.asList en realidad devuelve un java.util.Arrays.ArrayListque no es instanceofla otra clase. Entonces, una tercera advertencia es que si intenta usarlo en un contexto que requiere lo anterior, no funcionará.
Dave L.
352

(hilo antiguo, pero solo 2 centavos ya que ninguno menciona Guava u otras libs y algunos otros detalles)

Si puedes, usa guayaba

Vale la pena señalar la forma de la guayaba, que simplifica enormemente estas travesuras:

Uso

Para una lista inmutable

Usar la ImmutableListclase y sus of()y copyOf()fábrica métodos (elementos no puede ser nulo) :

List<String> il = ImmutableList.of("string", "elements");  // from varargs
List<String> il = ImmutableList.copyOf(aStringArray);      // from array

Para una lista mutable

Use la Listsclase y sus newArrayList()métodos de fábrica:

List<String> l1 = Lists.newArrayList(anotherListOrCollection);    // from collection
List<String> l2 = Lists.newArrayList(aStringArray);               // from array
List<String> l3 = Lists.newArrayList("or", "string", "elements"); // from varargs

Tenga en cuenta también los métodos similares para otras estructuras de datos en otras clases, por ejemplo en Sets.

¿Por qué guayaba?

La atracción principal podría ser reducir el desorden debido a los genéricos para la seguridad de tipos, ya que el uso de los métodos de la fábrica de guayaba permite inferir los tipos la mayor parte del tiempo. Sin embargo, este argumento tiene menos agua desde que Java 7 llegó con el nuevo operador de diamantes.

Pero no es la única razón (y Java 7 aún no está en todas partes): la sintaxis abreviada también es muy útil, y los inicializadores de métodos, como se ve arriba, permiten escribir código más expresivo. Lo haces en una llamada de guayaba lo que toma 2 con las colecciones de Java actuales.


Si no puedes ...

Para una lista inmutable

Utilice la Arraysclase de JDK y su asList()método de fábrica, envuelto con un Collections.unmodifiableList():

List<String> l1 = Collections.unmodifiableList(Arrays.asList(anArrayOfElements));
List<String> l2 = Collections.unmodifiableList(Arrays.asList("element1", "element2"));

Tenga en cuenta que el tipo devuelto para asList()un Listuso de una concreta ArrayListaplicación, pero que no es java.util.ArrayList . Es un tipo interno, que emula, ArrayListpero en realidad hace referencia directa a la matriz pasada y la hace "escribir" (las modificaciones se reflejan en la matriz).

Prohíbe modificaciones a través de algunos de los Listmétodos de la API simplemente extendiendo un AbstractList(por lo tanto, agregar o eliminar elementos no es compatible), sin embargo, permite que las llamadas set()anulen elementos. Por lo tanto, esta lista no es realmente inmutable y asList()debe incluirse un llamado a Collections.unmodifiableList().

Vea el siguiente paso si necesita una lista mutable.

Para una lista mutable

Igual que el anterior, pero envuelto con un real java.util.ArrayList:

List<String> l1  = new ArrayList<String>(Arrays.asList(array));    // Java 1.5 to 1.6
List<String> l1b = new ArrayList<>(Arrays.asList(array));          // Java 1.7+
List<String> l2  = new ArrayList<String>(Arrays.asList("a", "b")); // Java 1.5 to 1.6
List<String> l2b = new ArrayList<>(Arrays.asList("a", "b"));       // Java 1.7+

Para fines educativos: la buena manera manual

// for Java 1.5+
static <T> List<T> arrayToList(final T[] array) {
  final List<T> l = new ArrayList<T>(array.length);

  for (final T s : array) {
    l.add(s);
  }
  return (l);
}

// for Java < 1.5 (no generics, no compile-time type-safety, boo!)
static List arrayToList(final Object[] array) {
  final List l = new ArrayList(array.length);

  for (int i = 0; i < array.length; i++) {
    l.add(array[i]);
  }
  return (l);
}
haylem
fuente
27
+1 Pero tenga en cuenta que el Listdevuelto por Arrays.asListes mutable, ya que aún puede setelementos, simplemente no es redimensionable. Para listas inmutables sin guayaba, puede mencionar Collections.unmodifiableList.
Paul Bellora
1
@haylem En su sección Para fines educativos: la buena manera manual , su arrayToListpara Java 1.5+ es incorrecto. Usted está instanciando listas de String, y tratando de recuperar cadenas de la matriz dada, en lugar de utilizar el tipo de parámetro genérico, T. Aparte de eso, buena respuesta, y +1 por ser el único, incluida la forma manual.
Afsantos
Id 'cambie el nombre de su sección "Si no puede ... / Para una lista inmutable" a "Para una lista no modificable", ya que puede ser mutada por cambios posteriores en la matriz envuelta. Todavía está O(1), pero para la inmutabilidad, debe hacer una copia, por ejemplo, por Collections.unmodifiableList(new ArrayList<>(Arrays.asList(array))).
maaartinus
232

Como esta pregunta es bastante antigua, me sorprende que nadie haya sugerido la forma más simple todavía:

List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

A partir de Java 5, Arrays.asList()toma un parámetro varargs y no tiene que construir la matriz explícitamente.

Tim Büthe
fuente
77
En particular,List<String> a = Arrays.asList("first","second","third")
18446744073709551615
209
new ArrayList<T>(Arrays.asList(myArray));

Asegúrese de que myArraysea ​​del mismo tipo que T. Obtendrá un error de compilación si intenta crear un archivo a List<Integer>partir de una matriz de int, por ejemplo.

Bill el lagarto
fuente
103

Otra forma (aunque esencialmente equivalente a la new ArrayList(Arrays.asList(array))solución en cuanto a rendimiento:

Collections.addAll(arraylist, array);
Peter Tseng
fuente
97

Java 9

En Java 9 , puede usar List.ofel método de fábrica estático para crear un Listliteral. Algo como lo siguiente:

List<Element> elements = List.of(new Element(1), new Element(2), new Element(3));

Esto devolvería una lista inmutable que contiene tres elementos. Si quieres una lista mutable , pasa esa lista al ArrayListconstructor:

new ArrayList<>(List.of(// elements vararg))

JEP 269: Métodos convenientes de fábrica para colecciones

JEP 269 proporciona algunos métodos de fábrica convenientes para Java Collections API. Estos métodos de fábrica estáticas e inmutables están integrados en los List, Sety Maplas interfaces en Java 9 y posterior.

Ali Dehghani
fuente
List.of () no devolverá una instancia de java.util.ArrayList, como se solicitó en la pregunta original. Por lo tanto, solo la segunda opción es una respuesta válida.
tquadrat el
84

Probablemente solo necesite una Lista, no una ArrayList. En ese caso, solo puedes hacer:

List<Element> arraylist = Arrays.asList(array);
Dormir
fuente
8
Eso estará respaldado por la matriz de entrada original, razón por la cual (probablemente) desee envolverlo en una nueva ArrayList.
Bill the Lizard el
16
Ten cuidado con esta solución. Si observa, las matrices NO ESTÁN devolviendo una verdadera java.util.ArrayList. Está devolviendo una clase interna que implementa los métodos requeridos, pero no puede cambiar los miembros en la lista. Es simplemente un contenedor alrededor de una matriz.
Mikezx6r
1
Puede lanzar el elemento List <Element> a una ArrayList <Element>
monksy
12
@ Mikezx6r: pequeña corrección : es una lista de tamaño fijo. ¡Puede cambiar los elementos de la lista ( setmétodo), no puede cambiar el tamaño de la lista (no addo removeelementos)!
user85421
1
Sí, con la advertencia de que depende de lo que quieras hacer con la lista. Vale la pena señalar que si el OP simplemente quiere recorrer los elementos, la matriz no tiene que convertirse en absoluto.
PaulMurrayCbr
69

Otra actualización, casi terminando el año 2014, también puede hacerlo con Java 8:

ArrayList<Element> arrayList = Stream.of(myArray).collect(Collectors.toCollection(ArrayList::new));

Se guardarían algunos caracteres, si esto pudiera ser solo un List

List<Element> list = Stream.of(myArray).collect(Collectors.toList());
whyem
fuente
8
Probablemente sea mejor no depender de la implementación, pero en Collectors.toList()realidad devuelve un ArrayList.
bcsb1001
uso incorrecto de Stream.of (...); eso creará una secuencia de un elemento. Utilice Arrays.stream en su lugar
Patrick Parker
No lo creo, las 2 opciones son válidas, pero Arrays.stream es ligeramente 'mejor' ya que puede crearlo con un tamaño fijo, utilizando el método de sobrecarga con los argumentos 'inicio', 'fin'. Ver también: stackoverflow.com/a/27888447/2619091
whyem el
41

Si utiliza :

new ArrayList<T>(Arrays.asList(myArray));

¡ puedes crear y llenar dos listas! Llenar dos veces una lista grande es exactamente lo que no desea hacer, ya que creará otra Object[]matriz cada vez que deba ampliarse la capacidad.

Afortunadamente, la implementación de JDK es rápida y Arrays.asList(a[])está muy bien hecha. Crea una especie de ArrayList llamada Arrays.ArrayList donde los datos del Objeto [] apuntan directamente a la matriz.

// in Arrays
@SafeVarargs
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
//still in Arrays, creating a private unseen class
private static class ArrayList<E>

    private final E[] a;    
    ArrayList(E[] array) {
        a = array; // you point to the previous array
    }
    ....
}

¡El lado peligroso es que si cambia la matriz inicial, cambia la Lista! ¿Estás seguro de que quieres eso? Tal vez si tal vez no.

Si no, la forma más comprensible es hacer esto:

ArrayList<Element> list = new ArrayList<Element>(myArray.length); // you know the initial capacity
for (Element element : myArray) {
    list.add(element);
}

O como dijo @glglgl, puede crear otra ArrayList independiente con:

new ArrayList<T>(Arrays.asList(myArray));

Me encanta usar Collections, Arrayso guayaba. Pero si no encaja, o no lo siente, simplemente escriba otra línea poco elegante.

Nicolas Zozol
fuente
1
No veo la diferencia fundamental entre su ciclo al final de la respuesta y la new ArrayList<T>(Arrays.asList(myArray));parte que desalienta usar. Ambos hacen lo mismo y tienen la misma complejidad.
glglgl
Las Colecciones uno crean un puntero al comienzo de la matriz. Mi bucle crea muchos punteros: uno para cada miembro de la matriz. Entonces, si la matriz original cambia, mis punteros todavía se dirigen hacia los valores anteriores.
Nicolas Zozol
1
new ArrayList<T>(Arrays.asList(myArray));hace lo mismo, copia el asLista un ArrayList...
glglgl
37

En Java 9puedes usar:

List<String> list = List.of("Hello", "World", "from", "Java");
List<Integer> list = List.of(1, 2, 3, 4, 5);
MarekM
fuente
Tenga en cuenta que esto no es una ArrayList, ya que se solicitó explícitamente.
Dorian Gray
33

De acuerdo con la pregunta, la respuesta con Java 1.7 es:

ArrayList<Element> arraylist = new ArrayList<Element>(Arrays.<Element>asList(array));

Sin embargo, es mejor usar siempre la interfaz:

List<Element> arraylist = Arrays.<Element>asList(array);
nekperu15739
fuente
30
// Guava
import com.google.common.collect.ListsLists
...
List<String> list = Lists.newArrayList(aStringArray); 
Bohdan
fuente
21

como todos dijeron, esto lo hará

 new ArrayList<>(Arrays.asList("1","2","3","4"));

y la nueva forma común de crear una matriz es observableArrays

ObservableList: una lista que permite a los oyentes rastrear los cambios cuando ocurren.

para Java SE puedes probar

FXCollections.observableArrayList(new Element(1), new Element(2), new Element(3));

eso es de acuerdo con Oracle Docs

observableArrayList () Crea una nueva lista observable vacía que está respaldada por una matriz de listas. observableArrayList (E ... items) Crea una nueva lista de matriz observable con elementos agregados.

Actualizar Java 9

También en Java 9 es un poco fácil:

List<String> list = List.of("element 1", "element 2", "element 3");
Abojemyeg
fuente
20

Desde Java 8 hay una manera más fácil de transformar:

public static <T> List<T> fromArray(T[] array) {
    return Arrays.stream(array).collect(toList());
}
Andrii Abramov
fuente
18

También puedes hacerlo con stream en Java 8.

 List<Element> elements = Arrays.stream(array).collect(Collectors.toList()); 
Vaseph
fuente
3
A partir de Java 8 , Collectors.toList()devolverá un ArrayList. Sin embargo, esto puede diferir en futuras versiones en Java. Si desea un tipo específico de colección, utilice Collectors.toCollection()en su lugar donde puede especificar qué tipo exacto de colección desea crear.
Raja Anbazhagan
14
  1. Si vemos la definición de Arrays.asList()método, obtendrá algo como esto:

     public static <T> List<T> asList(T... a) //varargs are of T type. 

    Entonces, puede inicializar arraylistasí:

     List<Element> arraylist = Arrays.asList(new Element(1), new Element(2), new Element(3));

    Nota : cada uno new Element(int args)se tratará como Objeto individual y se puede pasar como a var-args.

  2. Puede haber otra respuesta para esta pregunta también.
    Si ve una declaración para el java.util.Collections.addAll()método, obtendrá algo como esto:

    public static <T> boolean addAll(Collection<? super T> c, T... a);

    Entonces, este código también es útil para hacerlo

    Collections.addAll(arraylist, array);
Vikrant Kashyap
fuente
10

Otra forma simple es agregar todos los elementos de la matriz a una nueva ArrayList usando un ciclo for-each.

ArrayList<Element> list = new ArrayList<>();

for(Element e : array)
    list.add(e);
spencer.sm
fuente
10

Si la matriz es de un tipo primitivo, las respuestas dadas no funcionarán. Pero desde Java 8 puedes usar:

int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());
A1m
fuente
esta solución tampoco parece funcionar con chararray.
PixelMaster
8

Puedes hacerlo en Java 8 de la siguiente manera

ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());
Adit A. Pillai
fuente
1
Votados porque ese elenco parece muy peligroso. nada especifica que el tipo de lista que se devuelve es en realidad una ArrayList, como dice el javadoc: "No hay garantías sobre el tipo, mutabilidad, serialización o seguridad de subprocesos de la Lista devuelta"
Dorian Gray
1
Si desea crear explícitamente una ArrayList, intente esto:ArrayList<String> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));
Dorian Gray
8

Podemos convertir fácilmente una matriz a ArrayList. Usamos el addAll()método de la interfaz de Colección con el propósito de copiar contenido de una lista a otra.

 Arraylist arr = new Arraylist();
 arr.addAll(Arrays.asList(asset));
rashedcs
fuente
Esto es menos eficiente que la respuesta aceptada de 9 años.
AjahnCharles
2
Uno de ArrayListlos constructores acepta un ? extends Collection<T>argumento, haciendo que la llamada sea addAllredundante.
Tamoghna Chowdhury
7

Aunque hay muchas respuestas perfectamente escritas a esta pregunta, agregaré mis entradas.

Di que tienes Element[] array = { new Element(1), new Element(2), new Element(3) };

Nueva ArrayList se puede crear de las siguientes maneras

ArrayList<Element> arraylist_1 = new ArrayList<>(Arrays.asList(array));
ArrayList<Element> arraylist_2 = new ArrayList<>(
    Arrays.asList(new Element[] { new Element(1), new Element(2), new Element(3) }));

// Add through a collection
ArrayList<Element> arraylist_3 = new ArrayList<>();
Collections.addAll(arraylist_3, array);

Y son muy compatibles con todas las operaciones de ArrayList

arraylist_1.add(new Element(4)); // or remove(): Success
arraylist_2.add(new Element(4)); // or remove(): Success
arraylist_3.add(new Element(4)); // or remove(): Success

Pero las siguientes operaciones devuelven solo una vista de Lista de una ArrayList y no una ArrayList real.

// Returns a List view of array and not actual ArrayList
List<Element> listView_1 = (List<Element>) Arrays.asList(array);
List<Element> listView_2 = Arrays.asList(array);
List<Element> listView_3 = Arrays.asList(new Element(1), new Element(2), new Element(3));

Por lo tanto, darán error al intentar realizar algunas operaciones de ArrayList

listView_1.add(new Element(4)); // Error
listView_2.add(new Element(4)); // Error
listView_3.add(new Element(4)); // Error

Más sobre la representación de la lista de enlaces de matriz .

Devendra Lattu
fuente
7

La forma más sencilla de hacerlo es agregando el siguiente código. Tratado y probado.

String[] Array1={"one","two","three"};
ArrayList<String> s1= new ArrayList<String>(Arrays.asList(Array1));
Hemin
fuente
7

Otra solución Java8 (es posible que haya perdido la respuesta entre el conjunto grande. Si es así, mis disculpas). Esto crea una ArrayList (en lugar de una Lista), es decir, se pueden eliminar elementos

package package org.something.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Junk {

    static <T> ArrayList<T>  arrToArrayList(T[] arr){
        return Arrays.asList(arr)
            .stream()
            .collect(Collectors.toCollection(ArrayList::new));
    }

    public static void main(String[] args) {
        String[] sArr = new String[]{"Hello", "cruel", "world"};
        List<String> ret = arrToArrayList(sArr);
        // Verify one can remove an item and print list to verify so
        ret.remove(1);
        ret.stream()
            .forEach(System.out::println);
    }
}

La salida es ...
Hola
mundo

Vidente sin dientes
fuente
7

Use el siguiente código para convertir una matriz de elementos en una ArrayList.

Element[] array = {new Element(1), new Element(2), new Element(3)};

ArrayList<Element>elementArray=new ArrayList();
for(int i=0;i<array.length;i++) {
    elementArray.add(array[i]);
}
Kavinda Pushpitha
fuente
5

Ya todos han proporcionado suficiente respuesta buena para su problema. Ahora, de todas las sugerencias, debe decidir cuál se adaptará a sus necesidades. Hay dos tipos de colección que necesita saber. Una es una colección no modificada y otra colección que le permitirá modificar el objeto más adelante.

Entonces, aquí daré un breve ejemplo para dos casos de uso.

  • Creación de colección inmutable :: Cuando no desea modificar el objeto de colección después de la creación

    List<Element> elementList = Arrays.asList(array)

  • Creación de colección mutable :: Cuando desee modificar el objeto de colección creado después de la creación.

    List<Element> elementList = new ArrayList<Element>(Arrays.asList(array));

Sumit Das
fuente
List <Element> elementList = Arrays.asList (array) crea un contenedor sobre la matriz original que hace que la matriz original esté disponible como List. Por lo tanto, se crea un objeto contenedor, no se copia nada de la matriz original. Por lo tanto, no se permiten operaciones como agregar o quitar elementos.
Priyanka
3
Tenga en cuenta que su "colección inmutable" no es realmente inmutable: lo que Listdevuelve Arrays.asListes solo un contenedor sobre la matriz original y permite acceder y modificar elementos individuales a través de gety set. Probablemente debería aclarar que quiere decir "no agregar o quitar elementos" en lugar de "inmutable", lo que significa no cambiar en absoluto.
Tamoghna Chowdhury
5

Matriz de objeto dada:

Element[] array = {new Element(1), new Element(2), new Element(3) , new Element(2)};

Convertir matriz a lista:

    List<Element> list = Arrays.stream(array).collect(Collectors.toList());

Convertir matriz a ArrayList

    ArrayList<Element> arrayList = Arrays.stream(array)
                                       .collect(Collectors.toCollection(ArrayList::new));

Convertir matriz a LinkedList

    LinkedList<Element> linkedList = Arrays.stream(array)
                     .collect(Collectors.toCollection(LinkedList::new));

Lista de impresión:

    list.forEach(element -> {
        System.out.println(element.i);
    });

SALIDA

1

2

3

Arpan Saini
fuente
4

La clase Arrays de Java 8 proporciona un método stream () que tiene versiones sobrecargadas que aceptan tanto matrices primitivas como matrices de objetos.

/**** Converting a Primitive 'int' Array to List ****/

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

List<Integer> integerList1 = Arrays.stream(intArray).boxed().collect(Collectors.toList());

/**** 'IntStream.of' or 'Arrays.stream' Gives The Same Output ****/

List<Integer> integerList2 = IntStream.of(intArray).boxed().collect(Collectors.toList());

/**** Converting an 'Integer' Array to List ****/

Integer integerArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

List<Integer> integerList3 = Arrays.stream(integerArray).collect(Collectors.toList());
Himanshu Dave
fuente
3

El siguiente código parece una buena manera de hacer esto.

new ArrayList<T>(Arrays.asList(myArray));
Singh123
fuente