Criar uma matriz de listas de matrizes

175

Eu estou querendo criar uma matriz de arraylist como abaixo:

ArrayList<Individual>[] group = new ArrayList<Individual>()[4]

Mas não está compilando. Como posso fazer isso?

do utilizador
fonte
8
Não misture matrizes e coleções. De fato, não use matrizes, a menos que esteja lidando com primitivos (ou saiba o que está fazendo). Matrizes são um pesadelo de usabilidade, elas tornam seu código insustentável.
Sean Patrick Floyd
13
@SeanPatrickFloyd Você pode explicar por que as matrizes são um pesadelo na usabilidade?
usuário
3
@crucifiedsoul com certeza. um array não pode crescer, você não pode inserir qualquer coisa em uma matriz, uma matriz não substituir métodos padrão como iguais hashcode ou toString etc.
Sean Patrick Floyd
9
@SeanPatrickFloyd ok - bem, preciso exatamente de quatro listas de matriz - planejo acessar cada uma por índice - não preciso que a matriz externa cresça ou encolha - não preciso de toString ou hashcode etc. - - para mim, uma matriz é a escolha óbvia aqui - o que você recomendaria como alternativa nessa situação?
BrainSlugs83
4
Ok, esta é uma pergunta antiga, mas vou fazer assim mesmo e ver se alguém responde. Estou vendo todo mundo falando sobre por que uma matriz de listas é uma péssima idéia, uma prática ruim de codificação etc. Eu procurei isso porque estou aprendendo a fazer cadeias de hash, e a definição de uma cadeia de hash é uma matriz de listas! Então, como exatamente uma estrutura central de dados de programação pode ser uma prática terrível de codificação? Ou isso apenas se enquadra na categoria IYKWYD mencionada pela @Sean?
jimboweb

Respostas:

142

Conforme a documentação da Oracle :

"Você não pode criar matrizes de tipos parametrizados"

Em vez disso, você pode fazer:

ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);

Como sugerido por Tom Hawting - tackline, é ainda melhor fazer:

List<List<Individual>> group = new ArrayList<List<Individual>>(4);
MByD
fonte
20
List<List<Individual>> group = new ArrayList<List<Individual>>();provavelmente seria melhor.
Tom Hawtin - tackline
4
O que significa "não é possível criar uma matriz do tipo genérico"? Isso realmente não faz sentido para mim, porque não é genérico se você fornecer o que é suposto conter, certo?
Andy Andy
5
Estou surpreso com os votos positivos, pois ele não responde à pergunta (ou seja, eu quero fazer isso, como posso fazê-lo). Exceto, talvez, a primeira frase.
Florian F
15
Por que a referência de lista é melhor que ArrayList?
shifu 8/07/2015
3
@shifu uma referência de lista é mais geral que ArrayList; declarar como Lista abstrai a API de ArrayList que se estende além da API de lista. Isso é bom porque simplifica a referência à Lista cuja API provavelmente possui a totalidade do que a Lista é necessária, sem sobrecarregar a API dessa referência com os extras que o ArrayList possui. Você só deve declarar como ArrayList se precisar que algo específico de sua API esteja disponível via referência.
Cellepo # 22/16
98

Como os outros mencionaram, provavelmente é melhor usar outra lista para armazenar o ArrayList, mas se você precisar usar um array:

ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];
Marcus
fonte
4
Ninguém parece explicar bem o porquê e eu gosto do seu snippet acima. por que você recomenda o uso da lista sobre isso?
clankill3r
3
Se o grupo de matrizes não for alterado, essa abordagem será melhor, porque as matrizes são mais rápidas que as classes List <>.
Borzh
33
Obrigado por realmente responder à pergunta. Não há razão lógica para presumir automaticamente que uma lista é preferível a uma matriz sem contexto adicional.
Special Sauce
3
Alguma razão pela qual isso seria preferível a @kelvincer Answer ( ArrayList<String>[] group = new ArrayList[4])? Que boa ação extra o elenco faz?
22616 cellepo
2
Você deve new ArrayList<?>[N]evitar o uso de um tipo bruto.
Radiodef 16/05/19
80

Isso funciona:

ArrayList<String>[] group = new ArrayList[4];
Kelvincer
fonte
1
Este satisfyingly tem o benefício desejado que a adição de um ArrayList de qualquer objeto além String (ou seja: ArrayList<String>em vez de ArrayList<NotString>) a groupnão compilar
cellepo
12
Isso produz um aviso:Note: hello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
matemática
24

Você pode criar uma classe estendendo ArrayList

class IndividualList extends ArrayList<Individual> {

}

e depois crie a matriz

IndividualList[] group = new IndividualList[10];
user2558221
fonte
17

Eu não entendo totalmente, por que todo mundo está sugerindo o tipo genérico sobre a matriz, particularmente para esta pergunta.

E se minha necessidade for indexar ndiferentes listas de matrizes.

Com a declaração List<List<Integer>>, preciso criar n ArrayList<Integer>objetos manualmente ou colocar um loop for para criar nlistas ou de alguma outra maneira, de qualquer forma, sempre será meu dever criar nlistas.

Não é ótimo se a declararmos através do casting como List<Integer>[] = (List<Integer>[]) new List<?>[somenumber]. Eu vejo isso como um bom design, onde não é necessário criar todo o objeto de indexação (listas de matriz) sozinho

Alguém pode me esclarecer por que esse (arrayform) será um design ruim e quais são suas desvantagens?

smslce
fonte
AFAICT parece ser um tipo de mentalidade de culto à carga induzida pelo terrível sistema de digitação que Java traz para a mesa.
BrainSlugs83
@smsIce: Não é um design ruim. O problema é que muitos escritores não lêem a questão completa ou a entendem claramente.
Testo
16

Você pode criar Array of ArrayList

List<Integer>[] outer = new List[number];
for (int i = 0; i < number; i++) {
    outer[i] = new ArrayList<>();
}

Isso será útil em cenários como este. Você sabe o tamanho do exterior. Mas o tamanho dos interiores varia. Aqui você pode criar uma matriz de comprimento fixo que contém listas de Matrizes que variam de tamanho. Espero que isso seja útil para você.

No Java 8 e acima, você pode fazer isso de uma maneira muito melhor.

List<Integer>[] outer = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());

Ainda melhor usando a referência de método

List<Integer>[] outer = new List[10];
Arrays.setAll(outer,  ArrayList :: new);
Arjun Nagathankandy
fonte
2
Quando você usa o ArrayList::new, ele chamará o ArrayList(int)contructor com o índice atual como argumento - ArrayList (1), ArrayList (2), ArrayList (3) etc.). dependendo do seu uso. Eu desencorajaria usá-lo e, em vez disso, preferiria a segunda abordagem na qual você mesmo chama o construtor em sua expressão lambda.
Genhis 15/07/19
8

Isso funciona, matriz de ArrayList. Tente entender como funciona.

import java.util.*;

public class ArrayOfArrayList {
    public static void main(String[] args) {

        // Put the length of the array you need
        ArrayList<String>[] group = new ArrayList[15];
        for (int x = 0; x < group.length; x++) {
            group[x] = new ArrayList<>();
        }

        //Add some thing to first array
        group[0].add("Some");
        group[0].add("Code");

        //Add some thing to Secondarray
        group[1].add("In here");

        //Try to output 'em
        System.out.println(group[0]);
        System.out.println(group[1]);
    }
}

Créditos ao Kelvincer por alguns códigos.

Rico
fonte
6

O problema com esta situação é que, usando uma lista de matrizes, você obtém uma complexidade temporal de o (n) para adicionar em uma posição específica. Se você usa uma matriz, cria um local de memória declarando sua matriz, portanto é constante

Mark Odey
fonte
Adicionar em uma posição específica é O (n) para a matriz e ArrayList. O preenchimento também é O (n) para matrizes e ArrayList.
Navin
2
Adicionar em uma posição específica é O (1) para matrizes. É O (n) para ArrayList, mas O (1) para matrizes.
Aviemet 21/03/2014
3

Você não pode criar uma matriz do tipo genérico. Crie uma lista de ArrayLists:

 List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();

ou se você REALMENTE precisar de matriz (AVISO: design incorreto!):

 ArrayList[] group = new ArrayList[4];
Piotr Gwiazda
fonte
2
  1. Criação e inicialização

    Object[] yourArray = new Object[ARRAY_LENGTH];
  2. Acesso de gravação

    yourArray[i]= someArrayList;

    para acessar elementos de ArrayList interno:

    ((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
  3. Acesso de leitura

    para ler o elemento da matriz i como um ArrayList, use a conversão de tipo:

    someElement= (ArrayList<YourType>) yourArray[i];

    para o elemento da matriz i: ler o elemento ArrayList no índice j

    arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);
Amr Lotfy
fonte
2

List [] listArr = new ArrayList [4];

A linha acima dá aviso, mas funciona (ou seja, cria Array of ArrayList)

Ashutosh S
fonte
1

Para declarar estaticamente uma matriz de ArrayLists para, digamos, posições de sprite como Pontos:

ArrayList<Point>[] positionList = new ArrayList[2];

public Main(---) {
    positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
    positionList[1] = new ArrayList<Point>();
}

dinamicamente:

ArrayList<Point>[] positionList;
int numberOfLists;

public Main(---) {
    numberOfLists = 2;
    positionList = new ArrayList[numberOfLists];
    for(int i = 0; i < numberOfLists; i++) {
        positionList[i] = new ArrayList<Point>();
    }
}

Apesar dos cuidados e de algumas sugestões complexas aqui, achei uma matriz de ArrayLists uma solução elegante para representar ArrayLists relacionadas do mesmo tipo.

Androidcoder
fonte
1
ArrayList<String>[] lists = (ArrayList<String>[])new ArrayList[10]; 
Labeo
fonte
1

Você pode criar assim ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];

Você precisa criar uma matriz de tipo não genérico e depois convertê-la em uma genérica.

Tejendra
fonte
1

ArrayList<Integer>[] graph = new ArrayList[numCourses] Funciona.

xiankun zhu
fonte
0

Acho isso mais fácil de usar ...

static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
 group=new ArrayList[size];
 for(int i=0;i<size;i++)
 {
  group[i]=new ArrayList<Individual>();
 }
Creative_Cimmons
fonte
0

Você consegue fazer isso :

// Crie uma matriz do tipo ArrayList

`ArrayList<Integer>[] a = new ArrayList[n];`

// Para cada elemento da matriz, crie um ArrayList

for(int i=0; i<n; i++){ 
    a[i] = new ArrayList<Integer>();
}
Nishant Salhotra
fonte
0
ArrayList<String> al[] = new ArrayList[n+1];
for(int i = 0;i<n;i++){
   al[i] = new ArrayList<String>();
}
HeadAndTail
fonte
-1

você pode criar uma lista [] e inicializá-los pelo loop for. compila sem erros:

List<e>[] l;
for(int i = 0; i < l.length; i++){
    l[i] = new ArrayList<e>();
}

ele funciona com arrayList [] l também.

user3539906
fonte
2
l.lengthé indefinido no loop for. Isso pode ser um erro de tempo de execução.
precisa saber é o seguinte
Não é inicializado para ter um comprimento, ainda é um ponteiro nulo quando atinge o loop for. ie Lista <e> [] l = nova Lista [COMPRIMENTO];
Erik