Por que esse código lançar uma IndexOfOutBoundsException - aka, o que há com EnsureCapacity ()?
Pergunta
Considere os seguintes dois trechos de código:
int index = 676;
List<String> strings = new ArrayList<String>();
strings.add(index, "foo");
e
int index = 676;
List<String> strings = new ArrayList<String>();
strings.ensureCapacity(index);
strings.add(index, "foo");
No primeiro caso, eu não estou surpreso de ver um IndexOfOutBoundsException. De acordo com o API, add(int index, E element)
irá lançar uma IndexOfOutBoundsException "se o índice está fora de (index < 0 || index > size())
gama". O tamanho do strings
é 0 antes de quaisquer elementos foram adicionados, de modo índice será definitivamente maior do que o tamanho do ArrayList.
No entanto, no segundo caso, seria de esperar a chamada para ensureCapacity
a crescer strings
tal que a chamada para add
seria corretamente inserir o "foo"
corda no índice 676 - mas isso não acontece
-
Por que não?
-
O que devo fazer para que
add(index, "foo")
trabalha paraindex > strings.size()
?
Solução
A capacidade da matriz subjacente em um ArrayList é diferente dos métodos Lista de API de nível mais alto (adicionar, remover, etc.), e só fala para o tamanho da matriz de suporte. Se você deseja permitir a adição de elementos além da lista limites, você precisa código que você mesmo (ou encontrar uma coleção que faz isso por você) em uma classe de utilitário, povoando nulos, objetos vazios, ou o que sua espera de aplicação entre a nova índice e o tamanho de idade.
Outras dicas
ArrayList.ensureCapacity () não altera o tamanho real da lista (que é devolvido pelo tamanho ()), mas sim realocar o buffer interno de tal forma que não precisará realocar o buffer a crescer a este tamanho (quando você chama list.add (objeto).
/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*/
Tomar um palpite, eu acho que o que você está procurando
Integer index = Integer.valueOf(676);
Map<Integer,String> strings = new HashMap<Integer,String>();
strings.put(index, "foo");
o seu comprimento é de 676, mas você tem que lembrar que eles são baseados em zero, de modo que, na realidade, você iria querer índice -1 seria o seu número máximo.