JavaRush /Blogue Java /Random-PT /new ArrayList(????) como e onde é melhor inicializar
Vovan
Nível 22

new ArrayList(????) como e onde é melhor inicializar

Publicado no grupo Random-PT
Escrever código sem usar a estrutura de coleções seria uma loucura. Esta é uma peça maravilhosa de Java com muitas soluções interessantes. Mais importante ainda, diferentemente dos arrays, você não precisa se preocupar com tamanhos. O ArrayList crescerá até ficar sem memória. O desenvolvedor não precisa se preocupar com o tamanho inicial e com o erro ArrayIndexOutOfBoundsException . Mas e se houver uma condição para monitorar a quantidade de memória? Podemos usar a memória de forma eficiente ao trabalhar com coleções?
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.
No caso de 100 elementos, a JVM precisará criar um novo array várias vezes e copiar os elementos nele. Levando isso em consideração, se houver uma suposição sobre o tamanho necessário do array, é melhor definir a capacidade inicial próxima a ele. Aqui estão algumas diretrizes para ação:
  1. Crie uma coleção somente quando precisar dela , caso contrário, inicialize-a como nula ou use Collections.EMPTY_LIST .
  2. Se você souber o tamanho exato necessário , especifique-o no construtor da coleção.
  3. Se você tiver certeza de que o número de elementos não excederá 10 , fique à vontade para usar o construtor padrão.
  4. 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 .
  5. Se você inicializou uma coleção muito grande no início do método e deseja reduzi-la, existe o método trimToSize() .
É claro que essas diretrizes se aplicam ao trabalhar com coleções baseadas em array, e nada disso faz sentido no caso de uma lista vinculada. Na verdade, é improvável que esses problemas sejam os assassinos do programa, mas se houver uma oportunidade de fazer um pouco melhor, por que não aproveitá-la? Você tem alguma outra dica útil? Você encontrou maneiras de fazer as coisas funcionarem melhor? Ou tudo isso é desnecessário? O que você acha?
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION