Criar ArrayList a partir da matriz

3596

Eu tenho uma matriz que é inicializada como:

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

Eu gostaria de converter esse array em um objeto da ArrayListclasse.

ArrayList<Element> arraylist = ???;
Ron Tuffin
fonte
49
Em Java9 -> Lista <>> list = List.of ("Olá", "Mundo", "de", "Java");
MarekM 11/04
18
@MarekM Esta resposta está errada, pois isso não retorna um ArrayList. O Cartaz pediu especificamente por isso.
Dorian Gray
4
Acho que ele não utilizou a interface List, porque é uma prática recomendada. Mas se você quiser, aqui está - new ArrayList <> (List.of ("Hello", "World", "from", "Java"));
MarekM 17/10
10
O ponto não é sobre o uso da interface, o ponto é que, na sua solução, a lista retornada não é modificável. Isso pode ser mais um problema, e uma razão pela qual ele pediu para um ArrayList
Dorian Gray

Respostas:

4603
new ArrayList<>(Arrays.asList(array));
Tom
fonte
361
Sim. E no caso (mais comum) em que você deseja apenas uma lista, a new ArrayListchamada também é desnecessária.
Calum
143
@Luron - just useList<ClassName> list = Arrays.asList(array)
Pool
248
@Calum e @Pool - conforme observado abaixo na resposta de Alex Miller, usar Arrays.asList(array)sem passá-lo para um novo ArrayListobjeto fixará o tamanho da lista. Um dos motivos mais comuns para usar um ArrayListé poder alterar dinamicamente seu tamanho, e sua sugestão evitaria isso.
Code Jockey
130
Arrays.asList () é uma função horrível e você nunca deve apenas usar seu valor de retorno como está. Ele quebra o modelo de lista, portanto, sempre o use no formulário indicado aqui, mesmo que pareça redundante. Boa resposta.
Adam
83
@ Adam Por favor, estude o javadoc para java.util.List. O contrato para add permite que eles lançem uma UnsupportedOperationException. docs.oracle.com/javase/7/docs/api/java/util/… É certo que de uma perspectiva orientada a objetos não é muito bom que muitas vezes você precise conhecer a implementação concreta para usar uma coleção - isso foi uma escolha pragmática de design, a fim de manter a estrutura simples.
lbalazscs
918

Dado:

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

A resposta mais simples é:

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

Isso vai funcionar bem. Mas algumas advertências:

  1. A lista retornada de asList possui tamanho fixo . Portanto, se você deseja adicionar ou remover elementos da lista retornada no seu código, precisará envolvê-lo em um novo ArrayList. Caso contrário, você receberá um UnsupportedOperationException.
  2. A lista retornada asList()é apoiada pela matriz original. Se você modificar a matriz original, a lista também será modificada. Isso pode ser surpreendente.
Alex Miller
fonte
6
Qual é a complexidade do tempo de ambas as operações? Quero dizer, com e sem o uso explícito de construção de arraylist.
condenado
35
Arrays.asList () apenas cria um ArrayList envolvendo a matriz existente para que seja O (1).
Alex Miller #
27
O agrupamento em um novo ArrayList () fará com que todos os elementos da lista de tamanho fixo sejam iterados e adicionados ao novo ArrayList, assim como O (n).
Alex Miller #
8
a implementação de List retornada por asList () não implementa vários métodos da lista (como add (), remove (), clear (), etc ...), o que explica a UnsupportedOperationException. definitivamente uma ressalva ...
sethro
8
Quando a pergunta pede "um objeto da classe ArrayList", acho razoável assumir que a classe a que se refere é java.util.ArrayList. Arrays.asList realmente retorna um java.util.Arrays.ArrayListque não é instanceofa outra classe. Portanto, uma terceira ressalva é que, se você tentar usá-lo em um contexto exigindo o descrito acima, não funcionará.
Dave L.
352

(thread antigo, mas apenas 2 centavos, como nenhum menciona Goiaba ou outras bibliotecas e alguns outros detalhes)

Se puder, use goiaba

Vale ressaltar o caminho da goiaba, que simplifica bastante essas travessuras:

Uso

Para uma lista imutável

Use a ImmutableListclasse e seus métodos of()e copyOf()factory (os elementos não podem ser nulos) :

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

Para uma lista mutável

Use a Listsclasse e seus 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

Observe também os métodos semelhantes para outras estruturas de dados em outras classes, por exemplo em Sets.

Por que goiaba?

A principal atração poderia ser reduzir a desordem devido aos genéricos para a segurança do tipo, como o uso dos métodos da fábrica de goiaba permite que os tipos sejam inferidos na maioria das vezes. No entanto, esse argumento retém menos água desde que o Java 7 chegou com o novo operador de diamantes.

Mas esse não é o único motivo (e o Java 7 ainda não está em todo lugar): a sintaxe abreviada também é muito útil e os inicializadores de métodos, como visto acima, permitem escrever um código mais expressivo. Você faz em uma chamada Guava o que leva 2 com as coleções Java atuais.


Se você não pode ...

Para uma lista imutável

Use a Arraysclasse do JDK e seu asList()método de fábrica, envolvido por Collections.unmodifiableList():

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

Observe que o tipo retornado para asList()é Listusando uma ArrayListimplementação concreta , mas NÃO é java.util.ArrayList . É um tipo interno, que emula um, ArrayListmas na verdade faz referência direta à matriz passada e a faz "escrever" (as modificações são refletidas na matriz).

Ele proíbe modificações através de alguns dos Listmétodos da API, simplesmente estendendo um AbstractList(portanto, adicionar ou remover elementos não é suportado), mas permite que as chamadas set()substituam elementos. Portanto, esta lista não é verdadeiramente imutável e uma chamada a asList()ser cumprida Collections.unmodifiableList().

Veja o próximo passo se precisar de uma lista mutável.

Para uma lista mutável

O mesmo que acima, mas envolvido com um 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 fins educacionais: o bom e velho caminho 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
fonte
27
+1 Mas observe que o Listretorno de Arrays.asListé mutável, pois você ainda pode setelementos - ele não é redimensionável. Para listas imutáveis ​​sem goiaba, você pode mencionar Collections.unmodifiableList.
precisa saber é o seguinte
1
@haylem Na sua seção Para fins educacionais: A maneira manual do bom e velho , o seu arrayToListpara Java 1.5+ está incorreto. Você está instanciando listas Stringe tentando recuperar seqüências de caracteres da matriz especificada, em vez de usar o tipo de parâmetro genérico T. Fora isso, boa resposta e +1 por ser o único, incluindo a maneira manual.
afsantos 16/05
Id 'renomeie sua seção "Se você não pode ... / Para uma lista imutável" para "Para uma lista não modificável", pois ela pode ser alterada por alterações posteriores na matriz agrupada. Ainda é O(1), mas para a imutabilidade você precisa fazer uma cópia, por exemplo, por Collections.unmodifiableList(new ArrayList<>(Arrays.asList(array))).
Maaartinus 19/11/19
232

Como essa pergunta é bastante antiga, me surpreende que ninguém tenha sugerido a forma mais simples ainda:

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

No Java 5, Arrays.asList()assume um parâmetro varargs e você não precisa construir a matriz explicitamente.

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

Verifique se myArrayé do mesmo tipo que T. Você receberá um erro do compilador se tentar criar um List<Integer>de uma matriz de int, por exemplo.

Bill the Lizard
fonte
103

Outra maneira (embora essencialmente equivalente à new ArrayList(Arrays.asList(array))solução em termos de desempenho:

Collections.addAll(arraylist, array);
Peter Tseng
fonte
96

Java 9

No Java 9 , você pode usar o List.ofmétodo estático de fábrica para criar um Listliteral. Algo como o seguinte:

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

Isso retornaria uma lista imutável contendo três elementos. Se você deseja uma lista mutável , passe essa lista para o ArrayListconstrutor:

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

JEP 269: Métodos de Fábrica de Conveniência para Coleções

O JEP 269 fornece alguns métodos de fábrica convenientes para a API Java Collections . Estes métodos de fábrica estáticos imutáveis são incorporados nos List, Sete Mapinterfaces em Java 9 e posterior.

Ali Dehghani
fonte
List.of () não retornará uma instância de java.util.ArrayList, conforme solicitado na pergunta original. Portanto, apenas a segunda opção é uma resposta válida.
tquadrat
84

Você provavelmente só precisa de uma lista, não de um ArrayList. Nesse caso, você pode apenas fazer:

List<Element> arraylist = Arrays.asList(array);
Kip
fonte
8
Isso será apoiado pela matriz de entrada original, e é por isso que você (provavelmente) deseja agrupá-la em uma nova ArrayList.
Bill Bill Lizard #
16
Tenha cuidado com esta solução. Se você olhar, as matrizes NÃO retornam um java.util.ArrayList verdadeiro. Ele está retornando uma classe interna que implementa os métodos necessários, mas você não pode alterar os membros da lista. É apenas um invólucro em torno de uma matriz.
Mikezx6r 01/10/08
1
Você pode converter o List <Elemento> item para um ArrayList <Elemento>
monksy
12
@ Mikezx6r: pequena correção : é uma lista de tamanho fixo. Você pode alterar os elementos da lista ( setmétodo), não pode alterar o tamanho da lista (não addou removeelementos)!
User85421
1
Sim, com a ressalva de que depende do que você quer fazer com a lista. Vale a pena notar que, se o OP simplesmente deseja percorrer os elementos, a matriz não precisa ser convertida.
PaulMurrayCbr
69

Outra atualização, que termina quase o ano de 2014, também pode ser feita com o Java 8:

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

Alguns caracteres seriam salvos, se isso fosse apenas um List

List<Element> list = Stream.of(myArray).collect(Collectors.toList());
whyem
fonte
8
Provavelmente é melhor não depender da implementação, mas Collectors.toList()na verdade retorna um ArrayList.
bcsb1001
uso incorreto de Stream.of (...); que criará um fluxo de um elemento. Use Arrays.stream em vez disso
Patrick Parker
Eu acho que não, as 2 opções são válidas, mas o Arrays.stream é um pouco 'melhor', pois você pode criá-lo com tamanho fixo, usando o método de sobrecarga com argumentos 'start', 'end'. Veja também: stackoverflow.com/a/27888447/2619091
whyem
41

Se você usar :

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

você pode criar e preencher duas listas! Preencher duas vezes uma lista grande é exatamente o que você não quer fazer, porque criará outra Object[]matriz sempre que a capacidade precisar ser ampliada.

Felizmente, a implementação do JDK é rápida e Arrays.asList(a[])muito bem-feita. Ele cria um tipo de ArrayList chamado Arrays.ArrayList onde os dados do Object [] apontam diretamente para a 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
    }
    ....
}

O lado perigoso é que, se você alterar a matriz inicial, altera a Lista!Tem certeza de que quer isso? Talvez sim talvez não.

Caso contrário, a maneira mais compreensível é fazer isso:

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

Ou, como disse @glglgl, você pode criar outra ArrayList independente com:

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

Gosto de usar Collections, Arraysou goiaba. Mas se não se encaixar, ou você não sentir, basta escrever outra linha deselegante.

Nicolas Zozol
fonte
1
Não vejo a diferença fundamental entre o seu loop no final da resposta e a new ArrayList<T>(Arrays.asList(myArray));parte que você desencoraja a usar. Ambos fazem a mesma coisa e têm a mesma complexidade.
glglgl
O Coleções cria um ponteiro no início da matriz. Meu loop cria muitos ponteiros: um para cada membro da matriz. Portanto, se a matriz original mudar, meus apontadores ainda serão direcionados aos valores anteriores.
Nicolas Zozol 22/02
1
new ArrayList<T>(Arrays.asList(myArray));faz o mesmo, ele copia o asLista um ArrayList...
glglgl
37

Em Java 9você pode usar:

List<String> list = List.of("Hello", "World", "from", "Java");
List<Integer> list = List.of(1, 2, 3, 4, 5);
MarekM
fonte
Observe que este não é um ArrayList, como foi explicitamente solicitado.
Dorian Gray
33

De acordo com a pergunta, a resposta usando o java 1.7 é:

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

No entanto, é melhor sempre usar a interface:

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

como já foi dito, isso fará isso

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

e a maneira mais nova e comum de criar array é observableArrays

ObservableList: uma lista que permite que os ouvintes acompanhem as alterações quando elas ocorrem.

para Java SE, você pode tentar

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

isso é de acordo com o Oracle Docs

observableArrayList () Cria uma nova lista observável vazia, apoiada por uma lista de matrizes. observableArrayList (E ... itens) Cria uma nova lista de matrizes observáveis ​​com itens adicionados a ela.

Atualizar Java 9

também no Java 9 é um pouco fácil:

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

Desde o Java 8, há uma maneira mais fácil de transformar:

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

Você também pode fazê-lo com fluxo no Java 8.

 List<Element> elements = Arrays.stream(array).collect(Collectors.toList()); 
Vaseph
fonte
3
A partir do java 8 , Collectors.toList()retornará um ArrayList. No entanto, isso pode diferir em versões futuras no java. Se você deseja um tipo específico de coleção, use-o em Collectors.toCollection()vez de especificar o tipo exato de coleção que deseja criar.
Raja Anbazhagan
14
  1. Se virmos a definição de Arrays.asList()método, você obterá algo como isto:

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

    Portanto, você pode inicializar arraylistassim:

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

    Nota : cada um new Element(int args)será tratado como Objeto Individual e pode ser passado como um var-args.

  2. Também pode haver outra resposta para essa pergunta.
    Se você java.util.Collections.addAll()vir uma declaração para o método, obterá algo como isto:

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

    Portanto, esse código também é útil para fazer isso

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

Outra maneira simples é adicionar todos os elementos da matriz a um novo ArrayList usando um loop for-each.

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

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

Se a matriz for de um tipo primitivo, as respostas fornecidas não funcionarão. Mas desde o Java 8 você pode usar:

int[] array = new int[5];
Arrays.stream(array).boxed().collect(Collectors.toList());
A1m
fonte
esta solução também não parece funcionar com chararray.
PixelMaster 10/06
8

Você pode fazer isso no java 8 da seguinte maneira

ArrayList<Element> list = (ArrayList<Element>)Arrays.stream(array).collect(Collectors.toList());
Adit A. Pillai
fonte
1
Votado porque esse elenco parece muito perigoso. especifica nada que o tipo de lista que é devolvido é realmente um ArrayList, como os estados de javadoc: "Não há garantias sobre o tipo, a mutabilidade, a seriação, ou thread-segurança da lista retornada"
Dorian Grey
1
Se você deseja criar explicitamente um ArrayList, tente o seguinte:ArrayList<String> list = Arrays.stream(array).collect(Collectors.toCollection(ArrayList::new));
Dorian Gray
8

Podemos facilmente converter uma matriz para ArrayList. Usamos o addAll()método da interface Collection para copiar conteúdo de uma lista para outra.

 Arraylist arr = new Arraylist();
 arr.addAll(Arrays.asList(asset));
rashedcs
fonte
Isso é menos eficiente que a resposta de 9 anos aceita.
AjahnCharles
2
Um dos ArrayListconstrutores de s aceita um ? extends Collection<T>argumento, tornando a chamada addAllredundante.
Tamoghna Chowdhury
7

Mesmo que haja muitas respostas perfeitamente escritas para essa pergunta, acrescentarei minhas informações.

Diga que você tem Element[] array = { new Element(1), new Element(2), new Element(3) };

Nova ArrayList pode ser criada das seguintes maneiras

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

E eles suportam muito bem todas as operações do 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

Mas as operações a seguir retornam apenas uma exibição em lista de um ArrayList e não um 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));

Portanto, eles darão erro ao tentar fazer algumas operações ArrayList

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

Mais sobre Listar representação do link da matriz .

Devendra Lattu
fonte
7

A maneira mais simples de fazer isso é adicionando o código a seguir. Experimentado e testado.

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

Outra solução Java8 (eu posso ter perdido a resposta entre o grande conjunto. Se sim, minhas desculpas). Isso cria um ArrayList (ao contrário de uma lista), ou seja, é possível excluir 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);
    }
}

Output is ...
Hello
world

Vidente Desdentado
fonte
7

Use o código a seguir para converter uma matriz de elementos em um 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
fonte
5

Todos já forneceram uma resposta boa o suficiente para o seu problema. Agora, a partir de todas as sugestões, você precisa decidir qual será o seu requisito. Existem dois tipos de coleção que você precisa conhecer. Uma é a coleção não modificada e outra é a coleção que permitirá modificar o objeto posteriormente.

Então, aqui vou dar um breve exemplo para dois casos de uso.

  • Criação imutável de coleção :: Quando você não deseja modificar o objeto de coleção após a criação

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

  • Criação de coleção mutável :: Quando você pode modificar o objeto de coleção criado após a criação.

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

Sumit Das
fonte
List <Element> elementList = Arrays.asList (array) cria um wrapper sobre o array original que disponibiliza o array original como List. Portanto, um objeto wrapper é criado, nada é copiado da matriz original. Portanto, operações como adicionar ou remover elementos não são permitidas.
Priyanka
3
Observe que sua "coleção imutável" não é realmente imutável - o Listretorno de Arrays.asListé apenas um invólucro sobre a matriz original e permite que itens individuais sejam acessados ​​e modificados via gete set. Provavelmente, você deve esclarecer que quer dizer "não adicionar ou remover elementos" em vez de "imutável", o que significa que não muda nada.
Tamoghna Chowdhury
5

Matriz de objeto fornecido:

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

Converter matriz em lista:

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

Conversão Array para ArrayList

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

Converter matriz em LinkedList

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

Imprimir lista:

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

RESULTADO

1

2

3

Arpan Saini
fonte
4

A classe Arrays do Java 8 fornece um método stream () que possui versões sobrecarregadas, aceitando matrizes primitivas e matrizes 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
fonte
3

O código abaixo parece uma boa maneira de fazer isso.

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