Tamanho inicial para o ArrayList


257

Você pode definir o tamanho inicial de um ArrayList fazendo

ArrayList<Integer> arr=new ArrayList<Integer>(10);

No entanto, você não pode fazer

arr.add(5, 10);

porque causa uma exceção fora dos limites.

Qual é a utilidade de definir um tamanho inicial se você não pode acessar o espaço alocado?

A função add é definida add(int index, Object element)assim, não estou adicionando ao índice 10.


52
Na verdade, não é óbvio pelos documentos que uma lista precisa ter pelo menos n itens adicionados antes do set/additem n-1 .
— Percepção

5
Percepção: não sei se é óbvio, mas está especificado. É necessário ler o JavaDoc com atenção. Throws: IndexOutOfBoundsException - se o índice estiver fora do intervalo (índice <0 || índice> = tamanho ()).
— Natix

3
Hum, o construtor diz "Constrói uma lista vazia com a capacidade inicial especificada.", Assumindo a noção de uma lista vazia, não pode haver um índice 5. Mas concordo que isso pode não ser visível à primeira vista ...
— quaylar

12
Eu acho que também é justo dizer que, se você inicializar uma matriz para um valor específico, você assumirá que índices mais baixos do que esse valor estão disponíveis - e esse é um ArrayList. Eu, pessoalmente, gostaria de um método que me permitisse definir um tamanho para que eu pudesse colocar as coisas em índices específicos. Este método parece notavelmente ausente.
— Andrew Wyld

1
Que numbskull projetou as coleções dessa maneira ?! Isso força o trabalho redundante para instanciação paralela de uma estrutura com elementos de comprimento variável (ou seja, ArrayList <String []>, em que cada matriz pode ter um comprimento diferente). Se a memória já estiver alocada para que a lista não precise de realocação após a adição de N elementos, esses índices deverão estar diretamente acessíveis desde o início. Ninguém na Oracle aprendeu esse padrão depois de C / C ++, C #, Objective C e Swift ?!
— precisa saber é o seguinte

Respostas:


387

Você está confundindo o tamanho da lista de matrizes com sua capacidade:

  • o tamanho é o número de elementos na lista;
  • a capacidade é quantos elementos a lista pode acomodar potencialmente sem realocar suas estruturas internas.

Quando você liga new ArrayList<Integer>(10), está definindo a capacidade inicial da lista , não o tamanho. Em outras palavras, quando construída dessa maneira, a lista de matrizes inicia sua vida vazia.

Uma maneira de adicionar dez elementos à lista de matrizes é usando um loop:

for (int i = 0; i < 10; i++) {
  arr.add(0);
}

Feito isso, agora você pode modificar elementos nos índices 0..9.


51
+1: Um loop mais curto é while(arr.size() < 10) arr.add(0);Pode ser útil dizer que o tamanho precisa ser pelo menos 10. por exemplo, de modo que você pode usararr.set(9, n);
— Peter Lawrey

10
+1: Ótima resposta, eu daria +10 se pudesse. Não é imediatamente óbvio pela API porque você não pode definir AMBOS o tamanho inicial e a capacidade inicial em uma única chamada de construtor. Você meio que precisa ler a API e dizer "Ah, eu acho que o ArrayList não tem um método ou construtor para fazer isso"
— demongolem

@PeterLawrey Seu código pode ser mais curto, mas contém duas chamadas de método por iteração de loop, em vez de apenas uma.
— Neuralmer 04/04/19

@neuralmer Eu esperaria que size () e add () fossem incorporados, para que nenhuma chamada de método real ocorra em tempo de execução.
— Peter Lawrey

109

Se você deseja uma lista com um tamanho predefinido, também pode usar:

List<Integer> arr = Arrays.asList(new Integer[10]);

11
Pequena desvantagem aqui, o resultado Listé cheio de nulos. Com o Guava, podemos fazer o Ints.asList(new int[10])que inicializará nossa lista com 0s. Padrão limpo, obrigado pelo exemplo.
— precisa saber é o seguinte

1
As perguntas falam sobre ArrayList <E>. Você está usando a lista <E>. Ninguém observou isso ??? Além disso, eles votaram nessa resposta irrelevante ! Não nego sua resposta porque nunca o faço. Simplesmente ... Deus!
— Apostolos

3
O @Apostolos ArrayListé uma implementação da Listinterface e Arrays.asListretorna um ArrayList. Eu sugiro que você procure polimorfismo.
— Liam Potter

Isso retorna uma lista com um tamanho fixo. Tentando adicionar mais elementos lançaUnsupportedOperationException
— Koray Tugay 03/03

47

se você deseja usar Collections.fill (list, obj); para preencher a lista com um objeto repetido, alternativamente, você pode usar

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

a linha copia 10 vezes 0 na sua ArrayList


20

A capacidade de um ArrayListnão é igual ao seu tamanho . Tamanho é igual ao número de elementos contidos no ArrayList(e em qualquer outroList implementação).

A capacidade é apenas o comprimento da matriz subjacente, usada para armazenar internamente os elementos da ArrayList, e é sempre maior ou igual ao tamanho da lista.

Ao chamar set(index, element)a lista, isso indexse refere ao número real dos elementos da lista (= tamanho) (que é zero no seu código, portanto, AIOOBEé lançado), não ao comprimento da matriz (= capacidade) (que é um detalhe específico da implementação para o ArrayList).

O setmétodo é comum a todas as Listimplementações, como LinkedList, que na verdade não é implementado por uma matriz, mas como uma cadeia de entradas vinculada.

Edit : Você realmente usa o add(index, element)método, não set(index, element), mas o princípio é o mesmo aqui.


10

Se você deseja adicionar os elementos com o índice, você pode usar uma matriz.

    String [] test = new String[length];
    test[0] = "add";

5
O OP queria usar uma lista inicialmente ... não uma matriz.
— Stephan

9

10 é a capacidade inicial do AL, não o tamanho (que é 0). Você deve mencionar a capacidade inicial com algum valor alto quando tiver muitos elementos, pois evita a sobrecarga de expandir a capacidade à medida que continua adicionando elementos.


6

Eu acho que uma resposta exata para sua pergunta seria:

Definir um tamanho inicial em um ArrayList reduz o número. vezes a realocação da memória interna deve ocorrer. A lista é apoiada por uma matriz. Se você especificar, ou seja, a capacidade inicial 0, já na primeira inserção de um elemento, a matriz interna deverá ser redimensionada. Se você tiver uma idéia aproximada de quantos elementos sua lista conteria, definir a capacidade inicial reduziria o número. de realocações de memória acontecendo enquanto você usa a lista.


3

Isso pode ajudar alguém -

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));

3

Chegando atrasado, mas após o Java 8 , pessoalmente, considero esta abordagem a seguir com a StreamAPI mais concisa e pode ser uma alternativa à resposta aceita .

Por exemplo,

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

onde sizeé o Listtamanho desejado e sem a desvantagem mencionada aqui , todos os elementos no Listsão inicializados como0 .

(Fiz uma pesquisa rápida e não encontrei streamnenhuma resposta postada. Fique à vontade para me informar se essa resposta é redundante e posso removê-la)


1

No momento, não há elementos na sua lista, portanto você não pode adicionar ao índice 5 da lista quando ela não existir. Você está confundindo a capacidade da lista com seu tamanho atual.

Apenas ligue:

arr.add(10)

para adicionar o número inteiro ao seu ArrayList


1

Embora sua lista de matrizes tenha capacidade para 10, a lista real não possui elementos aqui. O método add é usado para inserir um elemento na lista real. Como ele não possui elementos, não é possível inserir um elemento no índice 5.


1

Se você deseja adicionar 10 itens ao seu, ArrayListtente:

for (int i = 0; i < 10; i++)
    arr.add(i);

Se você já declarou uma variável de tamanho de matriz, usaria a variável em sizevez do número '10'


1

Enfrentei o problema semelhante e, sabendo que o arrayList é uma implementação redimensionável da interface List, também espero que você possa adicionar elemento a qualquer ponto, mas pelo menos ter a opção de definir o tamanho inicial. De qualquer forma, você pode criar uma matriz primeiro e convertê-la em uma lista como:

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

ou

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);

0

ArrayList myList = new ArrayList (10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList){
        System.out.println("inside list : "+item);
    }

/ * Declare que o capasity inicial do arraylist não é nada além de poupar tempo de mudança internamente; quando adicionamos o elemento internamente, ele verifica a capasidade para aumentar a capasidade, você pode adicionar o elemento no índice 0 inicialmente, depois 1 e assim por diante. * /


0

Meus dois centavos Stream. Acho melhor usar

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

com a flexibilidade de colocar quaisquer valores iniciais.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.