2009-10-19 2 views

ответ

34

я вижу вопрос, являющийся opposite-

Когда следует использовать массив по списку?

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

списки намного проще в использовании (IMO), и имеют гораздо больше функциональность.

Примечание. Вам также следует подумать над тем, действительно ли что-то вроде набора или другой структуры данных лучше, чем список, за то, что вы пытаетесь сделать.

Каждая структура данных и импликация имеют разные плюсы и минусы. Выберите те, которые превосходят то, что вам нужно делать.

Если вам нужен get(), чтобы быть O (1) для любого предмета? Вероятно, используйте ArrayList, Need O (1) insert()? Возможно, связанный список. Need O (1) содержит()? Возможно, Hashset.

TLDR: Каждая структура данных хороша в некоторых вещах и плохо в других. Посмотрите на свои цели и выберите структуру данных, которая наилучшим образом соответствует данной проблеме.

Edit:

Одно не отметить, что вы лучше объявить переменную как его интерфейса (то есть список или очередь) , а не его реализации класса. Таким образом, вы можете изменить реализацию на более позднюю дату без изменения чего-либо еще в коде .

В качестве примера:

List<String> myList = new ArrayList<String>(); 

против

List<String> myList = new LinkedList<String>(); 

Обратите внимание, что MyList является список в обоих примерах. - Р. Bemrose

+0

Связанный список не является вложением O (1), если вы не вставляете элементы в начале или в конце. Его основная цель - выборочные реализации стеков и очередей. – serg

+0

Вставка со списком ссылок O (1) в известном месте. Вы можете сделать вкладку O (1) в середине списка. Поиск места для вставки может быть O (n), если ваш список не является очередью или стеком. Различие важно при попытке сравнить структуры данных. – Dolphin

+2

Нельзя заметить, что вам лучше объявить переменную как ее интерфейс (т. Е. Список или очередь), а не ее реализующий класс. Таким образом, вы можете изменить реализацию позже, не изменяя ничего в коде. – Powerlord

0

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

+2

Чтобы быть точным: если вам нравится микро-оптимизация, вы обычно используете массив. –

6

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

+0

«особенно поддержка итератора»: обратите внимание, что расширенный цикл for поддерживает массивы, а также списки. – akf

+0

Хотя он не такой функциональный, как истинный итератор, новый for-loop в Java 5 дает синтаксический сахар для итерации по массивам. –

+0

Правильно, как сказал Майкл, цикл for - синтаксический сахар. Бывают случаи, когда вам нужен ваш объект для реализации Iterator, например, передача списков таким вещам, как Comparator. –

1

Это зависит от того, какой список.

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

Лучше использовать ArrayList, если вы заранее не знаете, сколько элементов будет. ArrayList правильно амортизирует стоимость выращивания массива подкрепления при добавлении к нему большего количества элементов и подходит для случайного доступа, когда элементы находятся на своем месте. ArrayList можно эффективно сортировать.

0

Во многих случаях тип коллекции используется деталь реализации, которая не должна подвергаться воздействию внешнего мира. Чем более универсальным является ваш возвращаемый тип, тем больше гибкости вы впоследствии меняете реализацию.

Массивы (примитивный тип, т. Е. Новый int [10]) не являются общими, вы не сможете изменить свою реализацию без внутреннего преобразования или изменения кода клиента. Возможно, вы захотите рассмотреть Iterable как возвращаемый тип.

2

Если вы знаете, сколько вещей вы будете держать, вам понадобится массив. Мой экран 1024x768, и буфер пикселей для этого не изменится в размере когда-либо во время выполнения.

Если вы знаете, что вам нужно получить доступ к определенным индексам (перейдите к элементу № 763!), Используйте список массивов или массивов.

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

В целом, речь идет о аппаратных средствах, массивах, имеющих дело с пользователями, списками.

+0

Не уверен в примере экрана - вы можете изменить размер экрана в любое время. Это даже распространено, если вы, например, используете RemoteDesktop/citrix или переместите приложение на второй экран. – vdr

+1

Если вы перемещаете экран приложения к экрану, вы имеете дело с окном, а не с экраном, который имеет дело с пользователем, а не с оборудованием. Если вы открываете удаленный рабочий стол, это новая инициализация/время выполнения. Я не хочу слишком сильно задирать, но я хотел бы поддержать то, что я сказал. :) –

12

Эмпирические правила:

  • Используйте List для ссылочных типов.
  • Использование массивов для примитивов.
  • Если вам нужно иметь дело с API, который использует массивы, может быть полезно использовать массивы. OTOH, может быть полезно обеспечить защитное копирование с помощью системы типов с помощью List.
  • Если вы выполняете много операций типа в последовательности и не находитесь в критическом разделе производительности/памяти, используйте List.
  • Оптимизация на нижнем уровне может использовать массивы. Ожидайте гадости с оптимизацией на низком уровне.
+2

+1 для указания преимущества относительно примитивов. – Yishai

3

Всегда предпочитайте списки.

Массивы когда

  1. для списков параметров метода (я думаю, вы вынуждены использовать массивы здесь).
  2. Если вы хотите, чтобы ваши коллекции были ковариантными (массивы ссылочных типов ковариантны).
  3. Критический код производительности.
9

Большинство людей ответили на него уже.

Практически нет оснований использовать массив вместо списка. Основным исключением является примитивный массив (например, int[]). Вы не можете создать примитивный список (должен иметь List<Integer>).

Самое важное отличие состоит в том, что при использовании Списка вы можете решить, какая реализация будет использоваться. Наиболее очевидным является выбор LinkedList или ArrayList.

Я хотел бы отметить в этом ответе, что выбор реализации дает очень мелкозернистый контроль над данными, которые просто не доступны для массива:

  1. Вы можете предотвратить клиент от изменения списка, обернув ваш список в Collection.unmodifiableList
  2. Вы можете синхронизировать список для многопоточного использования Collection.synchronizedList
  3. Вы можете создать очередь фиксированной длины с реализацией LinkedBlockingQueue
  4. ... и т. Д.

В любом случае, даже если вы не хотите (сейчас) каких-либо дополнительных функций в списке. Просто используйте ArrayList и размер его с размером массива, который вы создали. Он будет использовать Array в back-end, а разница в производительности с реальным массивом будет незначительной. (за исключением примитивных массивов)

Смежные вопросы