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.

Cemre
fonte
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.

NPE
fonte
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]);
Gert Jan Schoneveld
fonte
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

Farzan Skt
fonte
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.

Natix
fonte
10

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

    String [] test = new String[length];
    test[0] = "add";
user3692587
fonte
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.

Bhesh Gurung
fonte
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.

quaylar
fonte
3

Isso pode ajudar alguém -

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));
Hrishikesh Kadam
fonte
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)

HT Koo
fonte
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

Hunter McMillen
fonte
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.

roll1987
fonte
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'

pantera
fonte
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);
desconhecido
fonte
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. * /

sambhu
fonte
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.

anch2150
fonte