Есть ли причины предпочесть массивы над ArrayLists?

Возможный дубликат:
Преимущества массивов

Привет,

Есть ли какие-либо причины, чтобы предпочесть Arrays (MyObject[]) над ArrayLists (List<MyObject>)? Единственное левое место для использования массивов - это примитивные типы данных (int, boolean и т.д.). Однако у меня нет разумного объяснения этого, это просто делает код немного более тонким.

В целом я использую List для обеспечения большей гибкости. Но есть ли причины использовать реальные массивы?

Я хотел бы знать, наилучшие пожелания

Ответы

Ответ 1

Я предпочитаю использовать Array над ArrayList, когда я знаю, что я буду работать только с фиксированным количеством элементов. Мои причины в основном субъективны, но я все равно перечисляю их здесь:

  • Использование классов Collection для примитивов заметно медленнее, поскольку они должны использовать autoboxing и wrappers.

  • Я предпочитаю более простой синтаксис [] для доступа к элементам над ArrayList get(). Это действительно становится более важным, когда мне нужны многомерные массивы.

  • ArrayList обычно выделяют примерно вдвое больше необходимой вам памяти, чтобы вы могли быстро добавлять элементы. Таким образом, есть потеря, если вы никогда не собираетесь добавлять больше предметов.

  • (Возможно, связано с предыдущей точкой). Я думаю, что ArrayList доступ медленнее обычных массивов вообще. Реализация ArrayList использует базовый массив, но все обращения должны проходить через методы get(), set(), remove() и т.д., Что означает, что он проходит через больше кода, чем простой доступ к массиву. Но я действительно не проверял разницу, поэтому я могу ошибаться.

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

Ответ 2

Обычно массивы имеют свои проблемы, например. тип безопасности:

Integer[] ints = new Integer[10];
Number[] nums = ints; //that shouldn't be allowed
nums[3] = Double.valueOf[3.14]; //Ouch!

Они также не хорошо сочетаются с коллекциями. Таким образом, вы должны предпочесть Коллекции над массивами. Есть несколько вещей, где массивы могут быть более удобными. Как вы уже сказали, примитивные типы были бы причиной (хотя вы могли бы рассмотреть возможность использования таких коллекций, как Trove). Если массив скрыт в объекте и ему не нужно изменять его размер, достаточно использовать массивы, особенно если вам нужна вся производительность, которую вы можете получить (скажем, 3D и 4D векторы и матрицы для 3D-графики). Другой причиной использования массивов может быть, если ваш API имеет множество методов varargs.

BTW: есть симпатичный трюк с использованием массива, если вам нужны переменные переменные для анонимных классов:

public void f() {
   final int[] a = new int[1];
   new Thread(new Runnable() {
      public void run() {
         while(true) {
            System.out.println(a[0]++);
         }
      }    
   }).start();  
}

Обратите внимание, что вы не можете сделать это с переменной int, поскольку она должна быть окончательной.

Ответ 3

один для вас:

список сортировки (через j.u.Collections) сначала преобразуется в [], затем сортируется (который снова клонирует [] для сортировки слияния), а затем возвращает его в список. Вы понимаете, что ArrayList имеет вспомогательный объект [] под обложкой.

В тот же день был случай, когда ArrayList.get не был встроен компилятором -client hotspot, но теперь я думаю, что исправлено. Таким образом, проблема с производительностью с использованием ArrayList по сравнению с Object [] не так жестка, случай, примененный к соответствующему типу, по-прежнему стоит несколько часов (но это должно быть 99,99% от времени, предсказанного CPU); доступ к элементам ArrayList может стоить еще один кэш-пропуск больше и так (или первый доступ в основном)

В конце концов, это зависит от того, что вы делаете с вашим кодом.

Edit Забытый у вас может быть атомарный доступ к элементам массива (т.е. Материал CAS), один impl - j.u.c.atomic.AtomicReferenceArray. Это не самые практичные из-за того, что он не позволяет CAS Objec [] [], но Unsafe приходит на помощь.

Ответ 4

Я думаю, что основное отличие массива и списка состоит в том, что массив имеет фиксированную длину. Как только он полон, он полон. ArrayLists имеют гибкую длину и используют массивы для реализации. Когда arrayList недоступен, данные копируются в другой массив с большей емкостью (что то, чему меня учили один раз).

Массив все еще можно использовать, если у вас фиксированная длина данных. Поскольку массивы довольно примитивны, у них не так много методов для вызова и для всех. Преимущество использования этих массивов уже не так велико, потому что список массивов - это просто хорошие обертки для того, что вы хотите на Java или на любом другом языке.

Я думаю, что вы даже можете установить фиксированную емкость для арраистов в наши дни, поэтому даже это преимущество рушится.

Так есть ли какая-то причина предпочитать их? Нет, вероятно, нет, но он уверен, что у вас осталось немного места в памяти из-за базовой функциональности. Arraylist - довольно большая обертка и имеет большую гибкость, чего вы не всегда хотите.