2015-02-05 5 views
5

Я несколько опытный разработчик Java, и я продолжаю видеть вещи, как этотПреимущества создания ArrayList с начальной емкостью 0?

List<Integer> l = new ArrayList<Integer>(0); 

, который я действительно не могу понять. Какой смысл создавать ArrayList с начальной мощностью 0, когда вы знаете, что он будет расти за пределами возможностей?

Есть ли какие-либо известные преимущества этого?

+0

Возможный дубликат [В чем разница между ArrayList al = new ArrayList(); и ArrayList al = new ArrayList (0)?] (http://stackoverflow.com/questions/4666024/what-is-the-difference-between-arraylist-al-new-arraylist-and-arraylist -al) – Ascalonian

+0

Также : [Зачем начинать ArrayList с начальной пропускной способностью?] (Http://stackoverflow.com/questions/15430247/why-start-an-arraylist-with-an-initial-capacity) – Ascalonian

+2

@Ascalonian Я действительно знаю разницу , то, что я хочу знать, является преимуществом этого, вместо того, чтобы делать 'new ArrayList ()'. Не дуп. – Mauren

ответ

5

Она хранит размер (в памяти) в ArrayList очень небольшой, и это тактика, когда вы хотите, чтобы переменная быть ненулевым и готов к использованию, но не ожидать для List будет заполнен немедленно. Если вы ожидаете, что он будет заселен сразу, лучше всего дать ему большее начальное значение - любое «увеличение» ArrayList внутренне создает новый примитивный массив и копирует элементы. Рост ArrayList является дорогостоящим и должен быть сведен к минимуму.

Или, если вы создаете лотов экземпляров класса, каждый из которых содержит один из этих List объектов. Если вы не сразу планируете их заполнять, вы можете сохранить немного памяти, не выделив комнату.

Однако: Существует лучший способ: Collections.emptyList(). Обычно вы хотите напрямую защищать доступ к этому списку, и (в качестве примера) в своем классе предоставлять вызовы методов, специфичных для домена, которые работают на внутреннем List. Например, предположим, что у вас есть класс School, который содержит имена учеников List. (Держа это просто.)

public class School { 
    private List<String> studentNames = Collections.emptyList(); 

    public void addStudentName(String name) { 
     if (studentNames.isEmpty()) { 
      studentNames = new ArrayList<String>(); 
     } 
     studentNames.add(name); 
    } 

    public void removeStudentName(String name) { 
     studentNames.remove(name); 
     if (studentNames.isEmpty()) { 
      studentNames = Collections.emptyList(); // GC will deallocate the old List 
     } 
    } 
} 

Если вы готовы сделать isEmpty() проверки и выполнения инициализации/назначения, это лучшая альтернатива создания большого количества пустых ArrayList экземпляров, так как Collections.emptyList() статический экземпляр (существует только один) и не поддается изменению.

-2

В зависимости от контракта вы можете избежать NullPointerExceptions, не имея нулей. Это хорошая практика, в определенных ситуациях, см Effective Java Джошуа Блоха Пункт 43: Возвращение пустых массивов или коллекций, не обнуляет

+2

'new ArrayList <>()' также является пустым списком ... – Steffen

+0

Очевидно, что вопрос не противоречил ArrayList <>() vs ArrayList <>(), но просил общие причины использования ArrayList <> (0). Конечно, есть альтернативы. – barq

1

Это всегда лучше подход, чтобы дать большое значение (если вы, сколько список будет превышать) к массив, потому что это уменьшит изменение размера списка и, следовательно, оптимизирует время выполнения.

Initializing список массив со значением 0 создать Empty список массива, который reducing memory, если вы знаете, ваш список не представит более 10 контента.

+0

Да, это правильно, вместо того, чтобы хранить значение «null» в списке массивов, инициализируйте его нулями. –

+0

@vikingsteve Спасибо за ваш ответ, я отредактировал свой ответ. –

+0

Хорошо, я удалил свой нижний план. Теперь ваш ответ намного лучше, спасибо, что нашли время, чтобы отредактировать его снова. – vikingsteve

6

Для Java (или OpenJDK 7), не указав начальный размер дает вам список в пределах первоначального размера, установленного для . Поэтому, в зависимости от многих факторов использования вами списка, для инициализации списка может быть немного больше памяти и/или эффективности, размер 0.

Для java , указывая начальный размер 0 функционально эквивалентен не указывая начальный размер.

Однако это на самом деле менее эффективным, так как вызов конструктора с аргументом 0 берет вызов new Object[0], в то время как если вы укажете не-арг конструктор, начальный elementData для вашего списка устанавливается в статически определяется константой с именем EMPTY_ELEMENTDATA.

Соответствующий код из ArrayList источника:

/** 
* Shared empty array instance used for empty instances. 
*/ 
private static final Object[] EMPTY_ELEMENTDATA = {}; 

Другими словами, использование new ArrayList<Integer>(0); кажется излишним, нет никаких преимуществ в этом, и я хотел бы использовать вместо new ArrayList<Integer>();.

+0

Это верно для openjdk 7. Не верно для open jdk 6 см. -> http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ArrayList. java /? v = source – henry

+0

И это даже не верно для * всех * версий OpenJDK 7, похоже: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/ArrayList.java Но опять же я точно не знаю, насколько точным является grepcode ... –

+0

Спасибо, ребята, я обновил свой ответ, чтобы отразить. – vikingsteve

3
  • Если дополнения к этому ArrayList действительно маловероятно, и если это важно, чтобы размер ArrayList как минимум, то я могу видеть, что быть полезным.

  • Или если единственной целью этого ArrayList является возвращаемое значение из метода, где возврат пустого списка является специальным сообщением вызывающему функции, например «результаты не найдены».

  • В противном случае, не совсем.

1

По умолчанию ArrayList имеет емкость 10 и он изменяется каждый раз на 50%.

Используя нижнюю начальную емкость, вы можете иногда (теоретически) экономить память. С другой стороны, каждый размер времени занимает много времени. В большинстве случаев это всего лишь признак превентивной оптимизации.

+0

Это то, что я также думал, но только что проверил источник openjdk 7, который теперь оптимизирует, используя общий пустой элемент, как описано @vikingsteve. – henry