Surge uma pergunta padrão: como inicializar uma lista? O código abaixo não funcionará: Isso resultará em um erro de compilação: Os nomes das variáveis locais podem não ter sido inicializados . A especificação Java exige que todas as variáveis locais (aquelas que existem na pilha) sejam inicializadas com valores apropriados. É assim que você pode fazer: Sem dúvida, a lista deve ser inicializada. Você pode criar a lista na primeira linha ou pode fazer algo mais inteligente e usar a inicialização lenta como fizemos no método getAllNames() . Neste caso, a lista só será criada quando necessário - se as condições iniciais não forem atendidas, a lista nunca aparecerá no heap. Aqui chegamos à questão principal: que tamanho devemos definir para a lista? A melhor opção é dar-lhe o tamanho exato. Por exemplo: Neste caso, exatamente n nomes devem ser retornados e, como consequência, é criada uma coleção de n elementos. No entanto, o valor exato de n nem sempre é conhecido. Mesmo no exemplo dado, e se n=1000 e houvesse apenas 100 nomes disponíveis? Ao trabalhar com coleções, o método mais popular é chamar o construtor padrão. Se você olhar o código-fonte Java (versão 1.6) , como você pode ver, uma lista de 10 elementos é criada por padrão . Ou seja, podemos usar com segurança o construtor padrão quando não planejamos armazenar mais de 10 elementos na lista. O que acontece se você tentar adicionar o 11º elemento? Bem, nada de ruim... o elemento será adicionado com sucesso. Veja o método: O tamanho do array é controlado pelo método garantirCapacity . O tamanho aumenta 1,5 vezes . Um novo array é criado e os elementos são movidos para ele. Se definirmos o tamanho como 10, então no 11º elemento:
public List
getAllNames() { List
names; if (/*необходимые условия выполнены*/) { names = new ArrayList
(); /*заполнение списка*/ } return names; }
List
names = null; List
names = new ArrayList
(); List
names = new ArrayList
(0); List
names = new ArrayList
(size);
public List
getTopNames (int n) { List
names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList
(n); /*заполнение списка*/ } return names; }
names = new ArrayList
();
/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; }
public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
- o tamanho muda para 10 * 3/2 + 1 = 16
- próximo aumento = 16 * 3/2 + 1 = 25
- próximo aumento = 25 * 3/2 + 1 = 39 e assim por diante.
- Crie uma coleção somente quando precisar dela , caso contrário, inicialize-a como nula ou use Collections.EMPTY_LIST .
- Se você souber o tamanho exato necessário , especifique-o no construtor da coleção.
- Se você tiver certeza de que o número de elementos não excederá 10 , fique à vontade para usar o construtor padrão.
- O risco associado à criação de uma coleção de tamanho zero é que a frequência de criação de novos arrays e cópia de dados pode ser maior. Você precisa pensar com muito cuidado se o benefício de usar coleções de tamanho zero é realmente tão grande .
- Se você inicializou uma coleção muito grande no início do método e deseja reduzi-la, existe o método trimToSize() .
GO TO FULL VERSION