Когда использовать LinkedList над ArrayList?

Я всегда был один, чтобы просто использовать:

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

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

Когда LinkedList следует использовать ArrayList и наоборот?

2460
задан sdellysse 27 нояб. '08 в 4:36
источник поделиться

31 ответ

  • 1
  • 2

TL; DR ArrayList с ArrayDeque предпочтительнее в гораздо большем количестве случаев использования, чем LinkedList. Не уверен — просто начните с ArrayList.


LinkedList и ArrayList - две различные реализации интерфейса List. LinkedList реализует его с двусвязным списком. ArrayList реализует его с помощью динамически изменяющегося массива.

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

Для LinkedList<E>

  • get(int index) - среднее значение O (n/4)
  • add(E element) - O (1)
  • add(int index, E element) - среднее значение O (n/4)     но O (1), когда index = 0 < --- главное преимущество LinkedList<E>
  • remove(int index) - среднее значение O (n/4)
  • Iterator.remove() - O (1) < --- главное преимущество LinkedList<E>
  • ListIterator.add(E element) - O (1) < --- главное преимущество LinkedList<E>

Примечание: O (n/4) является средним, O (1) лучшим случаем (например, index = 0), O (n/2) наихудший случай (средний список)

Для ArrayList<E>

  • get(int index) - это O (1) < --- главное преимущество ArrayList<E>
  • add(E element) является O (1) амортизированным, но O (n) наихудшим, так как массив должен быть изменен и скопирован
  • add(int index, E element) - среднее значение O (n/2)
  • remove(int index) - среднее значение O (n/2)
  • Iterator.remove() - среднее значение O (n/2)
  • ListIterator.add(E element) - среднее значение O (n/2)

Примечание: O (n/2) является средним, O (1) лучшим случаем (конец списка), O (n) наихудшим случаем (начало списка)

LinkedList<E> допускает вставки или удаления с постоянным временем, используя итераторы, но только последовательный доступ к элементам. Другими словами, вы можете перемещать список вперед или назад, но поиск позиции в списке занимает время, пропорциональное размеру списка. Javadoc говорит: "Операции, которые индексируют в список, будут пересекать список с начала или конца, в зависимости от того, что ближе", поэтому эти методы в среднем равны O (n/4), хотя O (1) для index = 0.

ArrayList<E>, с другой стороны, позволяют быстрый случайный доступ для чтения, поэтому вы можете захватывать любой элемент в постоянное время. Но добавление или удаление из любого места, кроме конца, требует смещения всех последних элементов, чтобы сделать открытие или заполнить пробел. Кроме того, если вы добавляете больше элементов, чем емкость базового массива, выделяется новый массив (в 1,5 раза больше), а старый массив копируется в новый, поэтому добавление к ArrayList равно O (n) в худшем случае, но в среднем в среднем.

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

Основные преимущества использования LinkedList возникают при повторном использовании существующих итераторов для вставки и удаления элементов. Затем эти операции можно выполнить в O (1) путем изменения только локального списка. В списке массивов остальная часть массива должна быть перемещена (т.е. Скопирована). С другой стороны, поиск в LinkedList означает следующие ссылки в O (n/2) для наихудшего случая, тогда как в ArrayList желаемое положение может быть математически вычислено и доступно в O (1).

Другое преимущество использования LinkedList возникает при добавлении или удалении из главы списка, поскольку эти операции - O (1), тогда как O (n) для ArrayList. Обратите внимание, что ArrayDeque может быть хорошей альтернативой LinkedList для добавления и удаления из головы, но это не List.

Кроме того, если у вас есть большие списки, имейте в виду, что использование памяти также отличается. Каждый элемент a LinkedList имеет больше накладных расходов, поскольку также сохраняются указатели на следующий и предыдущие элементы. ArrayLists не имеют этих накладных расходов. Тем не менее, ArrayLists занимает столько памяти, сколько выделено для емкости, независимо от того, были ли добавлены элементы.

Начальная емкость по умолчанию ArrayList по умолчанию довольно небольшая (10 из Java 1.4 - 1.8). Но поскольку базовая реализация представляет собой массив, массив должен быть изменен, если вы добавите много элементов. Чтобы избежать высокой стоимости изменения размера, когда вы знаете, что собираетесь добавить много элементов, постройте ArrayList с более высокой начальной емкостью.

2754
ответ дан Jonathan Tran 27 нояб. '08 в 4:49
источник поделиться

До сих пор никто, кажется, не обращал внимание на объем памяти каждого из этих списков, кроме общего мнения, что LinkedList "намного больше", чем ArrayList, поэтому я сделал некоторое количество хрустов, чтобы продемонстрировать, сколько списки занимают N нулевых ссылок.

Так как ссылки являются либо 32, либо 64 битами (даже при нулевом) в их относительных системах, я включил 4 набора данных для 32 и 64 бит LinkedLists и ArrayLists.

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

Примечание 2: (спасибо BeeOnRope) Поскольку CompressedOops по умолчанию используется с середины JDK6 и выше, приведенные ниже значения для 64-разрядных машин будут в основном соответствовать их 32-разрядным аналогам, если, конечно, вы конкретно выключите его.


Graph of LinkedList and ArrayList No. of Elements x Bytes


Результат ясно показывает, что LinkedList намного больше, чем ArrayList, особенно с очень большим количеством элементов. Если память является фактором, избегайте LinkedLists.

Следующие формулы, которые я использовал, дайте мне знать, если я сделал что-то неправильно, и я исправлю это. "b" - это 4 или 8 для 32 или 64-битных систем, а "n" - количество элементов. Обратите внимание, что причина модов заключается в том, что все объекты в java будут занимать не более 8 байтов независимо от того, используется ли это все или нет.

ArrayList:

ArrayList object header + size integer + modCount integer + array reference + (array oject header + b * n) + MOD(array oject, 8) + MOD(ArrayList object, 8) == 8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8) + MOD(8 + 4 + 4 + b + (12 + b * n) + MOD(12 + b * n, 8), 8)

LinkedList:

LinkedList object header + size integer + modCount integer + reference to header + reference to footer + (node object overhead + reference to previous element + reference to next element + reference to element) * n) + MOD(node object, 8) * n + MOD(LinkedList object, 8) == 8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n + MOD(8 + 4 + 4 + 2 * b + (8 + 3 * b) * n + MOD(8 + 3 * b, 8) * n, 8)
523
ответ дан Numeron 06 окт. '11 в 9:46
источник поделиться

ArrayList - это то, что вы хотите. LinkedList почти всегда является ошибкой (производительности).

Почему LinkedList отстой:

  • Он использует множество небольших объектов памяти и, следовательно, влияет на производительность в процессе.
  • Множество мелких объектов плохо для локализации кэша.
  • Любая индексированная операция требует обхода, то есть имеет O (n) производительность. Это не очевидно в исходном коде, что приводит к алгоритмам O (n) медленнее, чем при использовании ArrayList.
  • Получение хорошей производительности сложно.
  • Даже когда производительность большого вывода совпадает с ArrayList, в любом случае, вероятно, она будет значительно медленнее.
  • Это раздражает, чтобы видеть LinkedList в источнике, потому что это, вероятно, неправильный выбор.
181
ответ дан Tom Hawtin - tackline 27 нояб. '08 в 17:20
источник поделиться

Как человек, занимающийся разработкой оперативной производительности на очень крупных веб-сервисах SOA в течение примерно десятилетия, я бы предпочел поведение LinkedList над ArrayList. Хотя стационарная пропускная способность LinkedList хуже и, следовательно, может привести к покупке большего количества аппаратных средств - поведение ArrayList под давлением может привести к тому, что приложения в кластере будут расширять свои массивы почти синхронно, а большие размеры массивов могут привести к отсутствию реакции в приложении и отключении, находясь под давлением, что является катастрофическим поведением.

Аналогично, вы можете получить более высокую пропускную способность в приложении из сборщика мусора, используемого по умолчанию, но как только вы получите java-приложения с кучей 10 ГБ, вы можете завершить блокировку приложения на 25 секунд во время полного GC, что вызывает таймауты и сбои в приложениях SOA и удаляет ваши SLA, если это происходит слишком часто. Несмотря на то, что сборщик CMS потребляет больше ресурсов и не достигает такой же сырой пропускной способности, это гораздо лучший выбор, поскольку он имеет более предсказуемую и меньшую задержку.

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

122
ответ дан lamont 01 янв. '11 в 23:23
источник поделиться
Algorithm           ArrayList   LinkedList
seek front            O(1)         O(1)
seek back             O(1)         O(1)
seek to index         O(1)         O(N)
insert at front       O(N)         O(1)
insert at back        O(1)         O(1)
insert after an item  O(N)         O(1)

Алгоритмы: Big-Oh Notation

ArrayLists хороши для write-once-read-many или appenders, но плохо при добавлении/удалении спереди или в середине.

104
ответ дан Michael Munsey 08 апр. '10 в 23:33
источник поделиться

Да, я знаю, это древний вопрос, но я брошу свои два цента:

LinkedList почти всегда является неправильным выбором, с точки зрения производительности. Существуют некоторые очень специфические алгоритмы, для которых требуется ссылка LinkedList, но они очень и очень редки, и алгоритм обычно будет зависеть от способности LinkedList вставлять и удалять элементы в середине списка относительно быстро, как только вы переходите туда с ListIterator.

Существует один общий вариант использования, в котором LinkedList превосходит ArrayList: очередь. Однако, если ваша цель - производительность, вместо LinkedList вы также должны рассмотреть возможность использования ArrayBlockingQueue (если вы можете заранее определить верхнюю границу вашего размера очереди и можете позволить себе выделить всю память вверх), или это реализация CircularArrayList. (Да, это с 2001 года, так что вам нужно будет его обобщить, но я получил сопоставимые показатели производительности с тем, что цитируется в статье только в недавней JVM)

89
ответ дан Daniel Martin 19 мая '09 в 14:21
источник поделиться

Это вопрос эффективности. LinkedList быстро добавляет и удаляет элементы, но медленный доступ к определенному элементу. ArrayList быстро получает доступ к определенному элементу, но может быть медленным добавлением в любой конец и особенно медленным для удаления в середине.

Array vs ArrayList vs LinkedList vs Vector: - идет более подробно, как и

Связанный список

48
ответ дан dgtized 27 нояб. '08 в 4:39
источник поделиться

Правильно или неверно: Пожалуйста, выполните тест на месте и решите себя.

Изменить/удалить быстрее в LinkedList, чем в ArrayList.

ArrayList, поддерживаемый Array, который должен быть в два раза больше, хуже применяется при больших объемах.

Ниже приведен результат unit test для каждой операции. Цитирование задается в наносекундах.


                                ArrayList                      Linked List  

AddAll   (Insert)               101,16719                      2623,29291 

Add      (Insert-Sequentially)  152,46840                      966,62216

Add      (insert-randomly)      36527                          29193

remove   (Delete)               20,56,9095                     20,45,4904

contains (Search)               186,15,704                     189,64,981

            import org.junit.Assert;
            import org.junit.Test;

            import java.util.*;

            public class ArrayListVsLinkedList {
                private static final int MAX = 500000;
                String[] strings = maxArray();

                ////////////// ADD ALL ////////////////////////////////////////
                @Test
                public void arrayListAddAll() {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);
                    List<String> arrayList = new ArrayList<String>(MAX);

                    watch.start();
                    arrayList.addAll(stringList);
                    watch.totalTime("Array List addAll() = ");//101,16719 Nanoseconds
                }

                @Test
                public void linkedListAddAll() throws Exception {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);

                    watch.start();
                    List<String> linkedList = new LinkedList<String>();
                    linkedList.addAll(stringList);
                    watch.totalTime("Linked List addAll() = ");  //2623,29291 Nanoseconds
                }

                //Note: ArrayList is 26 time faster here than LinkedList for addAll()

                ///////////////// INSERT /////////////////////////////////////////////
                @Test
                public void arrayListAdd() {
                    Watch watch = new Watch();
                    List<String> arrayList = new ArrayList<String>(MAX);

                    watch.start();
                    for (String string : strings)
                        arrayList.add(string);
                    watch.totalTime("Array List add() = ");//152,46840 Nanoseconds
                }

                @Test
                public void linkedListAdd() {
                    Watch watch = new Watch();

                    List<String> linkedList = new LinkedList<String>();
                    watch.start();
                    for (String string : strings)
                        linkedList.add(string);
                    watch.totalTime("Linked List add() = ");  //966,62216 Nanoseconds
                }

                //Note: ArrayList is 9 times faster than LinkedList for add sequentially

                /////////////////// INSERT IN BETWEEN ///////////////////////////////////////

                @Test
                public void arrayListInsertOne() {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);
                    List<String> arrayList = new ArrayList<String>(MAX + MAX / 10);
                    arrayList.addAll(stringList);

                    String insertString0 = getString(true, MAX / 2 + 10);
                    String insertString1 = getString(true, MAX / 2 + 20);
                    String insertString2 = getString(true, MAX / 2 + 30);
                    String insertString3 = getString(true, MAX / 2 + 40);

                    watch.start();

                    arrayList.add(insertString0);
                    arrayList.add(insertString1);
                    arrayList.add(insertString2);
                    arrayList.add(insertString3);

                    watch.totalTime("Array List add() = ");//36527
                }

                @Test
                public void linkedListInsertOne() {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);
                    List<String> linkedList = new LinkedList<String>();
                    linkedList.addAll(stringList);

                    String insertString0 = getString(true, MAX / 2 + 10);
                    String insertString1 = getString(true, MAX / 2 + 20);
                    String insertString2 = getString(true, MAX / 2 + 30);
                    String insertString3 = getString(true, MAX / 2 + 40);

                    watch.start();

                    linkedList.add(insertString0);
                    linkedList.add(insertString1);
                    linkedList.add(insertString2);
                    linkedList.add(insertString3);

                    watch.totalTime("Linked List add = ");//29193
                }


                //Note: LinkedList is 3000 nanosecond faster than ArrayList for insert randomly.

                ////////////////// DELETE //////////////////////////////////////////////////////
                @Test
                public void arrayListRemove() throws Exception {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);
                    List<String> arrayList = new ArrayList<String>(MAX);

                    arrayList.addAll(stringList);
                    String searchString0 = getString(true, MAX / 2 + 10);
                    String searchString1 = getString(true, MAX / 2 + 20);

                    watch.start();
                    arrayList.remove(searchString0);
                    arrayList.remove(searchString1);
                    watch.totalTime("Array List remove() = ");//20,56,9095 Nanoseconds
                }

                @Test
                public void linkedListRemove() throws Exception {
                    Watch watch = new Watch();
                    List<String> linkedList = new LinkedList<String>();
                    linkedList.addAll(Arrays.asList(strings));

                    String searchString0 = getString(true, MAX / 2 + 10);
                    String searchString1 = getString(true, MAX / 2 + 20);

                    watch.start();
                    linkedList.remove(searchString0);
                    linkedList.remove(searchString1);
                    watch.totalTime("Linked List remove = ");//20,45,4904 Nanoseconds
                }

                //Note: LinkedList is 10 millisecond faster than ArrayList while removing item.

                ///////////////////// SEARCH ///////////////////////////////////////////
                @Test
                public void arrayListSearch() throws Exception {
                    Watch watch = new Watch();
                    List<String> stringList = Arrays.asList(strings);
                    List<String> arrayList = new ArrayList<String>(MAX);

                    arrayList.addAll(stringList);
                    String searchString0 = getString(true, MAX / 2 + 10);
                    String searchString1 = getString(true, MAX / 2 + 20);

                    watch.start();
                    arrayList.contains(searchString0);
                    arrayList.contains(searchString1);
                    watch.totalTime("Array List addAll() time = ");//186,15,704
                }

                @Test
                public void linkedListSearch() throws Exception {
                    Watch watch = new Watch();
                    List<String> linkedList = new LinkedList<String>();
                    linkedList.addAll(Arrays.asList(strings));

                    String searchString0 = getString(true, MAX / 2 + 10);
                    String searchString1 = getString(true, MAX / 2 + 20);

                    watch.start();
                    linkedList.contains(searchString0);
                    linkedList.contains(searchString1);
                    watch.totalTime("Linked List addAll() time = ");//189,64,981
                }

                //Note: Linked List is 500 Milliseconds faster than ArrayList

                class Watch {
                    private long startTime;
                    private long endTime;

                    public void start() {
                        startTime = System.nanoTime();
                    }

                    private void stop() {
                        endTime = System.nanoTime();
                    }

                    public void totalTime(String s) {
                        stop();
                        System.out.println(s + (endTime - startTime));
                    }
                }


                private String[] maxArray() {
                    String[] strings = new String[MAX];
                    Boolean result = Boolean.TRUE;
                    for (int i = 0; i < MAX; i++) {
                        strings[i] = getString(result, i);
                        result = !result;
                    }
                    return strings;
                }

                private String getString(Boolean result, int i) {
                    return String.valueOf(result) + i + String.valueOf(!result);
                }
            }
46
ответ дан Ash 22 сент. '11 в 1:59
источник поделиться

ArrayList по существу является массивом. LinkedList реализуется как двойной связанный список.

get довольно ясен. O (1) для ArrayList, потому что ArrayList допускает произвольный доступ с использованием индекса. O (n) для LinkedList, потому что он должен сначала найти индекс. Примечание. Существуют разные версии add и remove.

LinkedList быстрее добавляет и удаляет, но медленнее в get. Короче говоря, LinkedList следует отдать предпочтение, если:

  • нет большого количества случайного доступа элемента
  • существует большое количество операций добавления/удаления

=== ArrayList ===

  • add (E e)
        • добавить в конец ArrayList
        • требуется стоимость изменения размера памяти.
        • O (n) хуже, O (1) амортизировано
  • add (int index, элемент E)
        • добавить к определенной позиции индекса
        • требуют изменения и возможного изменения размера памяти
        • О (п)
  • удалить (индекс int)
        • удалить указанный элемент
        • требуют изменения и возможного изменения размера памяти
        • О (п)
  • remove (Object o)
        • удалить первое вхождение указанного элемента из этого списка
        • необходимо сначала выполнить поиск по элементу, а затем изменить и уменьшить стоимость изменения размера памяти.
        • О (п)

=== LinkedList ===

  • add (E e)
        • добавить в конец списка
        • О (1)
  • add (int index, элемент E)

        • вставить в указанное положение
        • нужно сначала найти позицию
        • О (п)
  • удалить()
        • удалить первый элемент списка
        • О (1)
  • удалить (индекс int)
        • удалить элемент с указанным индексом
        • нужно сначала найти элемент
        • О (п)
  • remove (Object o)
        • удалить первое вхождение указанного элемента
        • нужно сначала найти элемент
        • О (п)

Вот цифра из programcreek.com (add и remove - это первый тип, т.е. добавить элемент в конец списка и удалить элемент в указанной позиции в списке.):

enter image description here

33
ответ дан Ryan 21 апр. '13 в 3:03
источник поделиться

ArrayList является случайным образом доступным, а LinkedList действительно дешево расширять и удалять элементы. В большинстве случаев ArrayList в порядке.

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

28
ответ дан Dustin 27 нояб. '08 в 4:41
источник поделиться

1) Поиск: Операция поиска ArrayList довольно быстро по сравнению с операцией поиска LinkedList. get (int index) в ArrayList дает производительность O (1), а производительность LinkedList - O (n).

Причина: ArrayList поддерживает систему на основе индексов для своих элементов, поскольку она неявно использует структуру данных массива, что делает ее более быстрой для поиска элемента в списке. С другой стороны LinkedList реализует дважды связанный список, который требует обхода всех элементов для поиска элемента.

2) Удаление: Операция удаления LinkedList дает производительность O (1), в то время как ArrayList дает переменную производительность: O (n) в худшем случае (при удалении первого элемента) и O (1) в лучшем случае (При удалении последнего элемента).

Вывод: Удаление элемента LinkedList происходит быстрее по сравнению с ArrayList.

Причина: LinkedLists Каждый элемент поддерживает два указателя (адреса), которые указывают на оба соседних элемента в списке. Следовательно, для удаления требуется только изменение местоположения указателя в двух соседних узлах (элементах) node, которые будут удалены. В то время как в ArrayList все элементы необходимо сдвинуть, чтобы заполнить пространство, созданное удаленным элементом.

3) Вставка производительности: Метод добавления LinkedList дает производительность O (1), в то время как ArrayList дает O (n) в худшем случае. Причина та же, что и для удаления.

4) Накладные расходы памяти: ArrayList поддерживает индексы и данные элемента, в то время как LinkedList поддерживает данные элемента и два указателя для соседних узлов, следовательно, потребление памяти в LinkedList сравнительно велико.

Между этими классами несколько сходств, которые выглядят следующим образом:

Оба ArrayList и LinkedList - это реализация интерфейса List. Они оба поддерживают порядок вставки элементов, что означает, что при отображении элементов ArrayList и LinkedList набор результатов будет иметь тот же порядок, в котором элементы были вставлены в список. Оба эти класса не синхронизированы и могут быть синхронизированы явно с помощью метода Collections.synchronizedList. Итератор и listIterator, возвращаемые этими классами, являются неудачными (если список структурно изменен в любое время после создания итератора, любым способом, кроме как с помощью собственных методов удаления или добавления итераторов, итератор будет вызывать исключение ConcurrentModificationException).

Когда использовать LinkedList и когда использовать ArrayList?

1) Как объяснялось выше, операции вставки и удаления дают хорошую производительность (O (1)) в LinkedList по сравнению с ArrayList (O (n)). Следовательно, если в приложении есть требование частого добавления и удаления, тогда LinkedList - лучший выбор.

2) Операции поиска (get method) выполняются быстро в Arraylist (O (1)), но не в LinkedList (O (n)), так что если операций с добавлением и удалением меньше и больше запросов на поиск, ArrayList будет вашим лучший выбор.

24
ответ дан NoNaMe 07 июля '14 в 12:22
источник поделиться

Джошуа Блох, автор LinkedList:

Кто-нибудь действительно использует LinkedList? Я написал это, и я никогда не использую его.

Ссылка: https://twitter.com/joshbloch/status/583813919019573248

Мне жаль, что ответ был не таким информативным, как другие ответы, но я подумал, что это будет самым интересным и понятным.

19
ответ дан Ruslan 01 марта '17 в 13:47
источник поделиться

Я знаю, что это старый пост, но я честно не могу поверить, что никто не упоминал, что LinkedList реализует Deque. Просто посмотрите на методы в Deque (и Queue); если вы хотите провести честное сравнение, попробуйте запустить LinkedList против ArrayDeque и выполнить сравнение функций для функций.

16
ответ дан Ajax 19 апр. '13 в 10:26
источник поделиться

Если ваш код имеет add(0) и remove(0), используйте LinkedList и более красивые методы addFirst() и removeFirst(). В противном случае используйте ArrayList.

И, конечно, Guava ImmutableList ваш лучший друг.

15
ответ дан Jesse Wilson 28 нояб. '08 в 5:04
источник поделиться

Вот большая нотация O как в ArrayList, так и в LinkedList, а также в CopyOnWrite-ArrayList
ArrayList
get → O (1)
add → O (1)
содержит → O (n)
next → O (1)
удалить → O (n)
iterator.remove → O (n)


LinkedList
get → O (n)
add → O (1)
содержит → O (n)
next → O (1)
удалить → O (1)
iterator.remove → O (1)


CopyOnWrite-ArrayList
get → O (1)
add → O (n)
содержит → O (n)
next → O (1)
удалить → O (n)
iterator.remove → O (n)


Исходя из этого, вы должны решить, что выбрать:)

13
ответ дан Rajith Delantha 06 нояб. '12 в 17:32
источник поделиться

Здесь важно различать как

 Array List is better for storing and accessing data.

Linked List is better for manipulating data.
11
ответ дан ankit singh 26 апр. '16 в 14:35
источник поделиться

Посмотрите на изображение ниже.

http://javaconceptoftheday.com/wp-content/uploads/2014/12/ArrayListVsLinkedList.png

Источник изображения: ArrayList Vs LinkedList В Java.

11
ответ дан user2485429 01 апр. '15 в 20:16
источник поделиться

Давайте сравним LinkedList и ArrayList w.r.t. ниже параметров:

1. Реализация

ArrayList - это реализация интерфейса массива с изменяемым размером, в то время как

LinkedList - это реализация списка ссылок с двойным соединением.


2. Производительность

  • get (индекс int) или операция поиска

    Операция ArrayList get (int index) выполняется в постоянное время i.e O (1) while

    Время работы операции LinkedList get (int index) равно O (n).

    Причина того, что ArrayList быстрее, чем LinkedList, заключается в том, что ArrayList использует систему на основе индексов для своих элементов, поскольку она внутренне использует структуру данных массива, с другой стороны,

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

  • Вставить() или добавить операцию (объект)

    Вставки в LinkedList обычно бывают быстрыми, как сравнение с ArrayList. В добавлении или вставке LinkedList выполняется операция O (1).

    В то время как в ArrayList, если массив заполнен, то есть в худшем случае, есть дополнительные затраты на изменение размера массива и копирование элементов в новый массив, что делает время выполнения операции добавления в ArrayList O (n), в противном случае O (1).

  • удалить (int) операцию

    Удаление операции в LinkedList обычно совпадает с ArrayList, то есть O (n).

    В LinkedList существует два перегруженных метода удаления. один - remove() без какого-либо параметра, который удаляет головку списка и запускается в постоянное время O (1). Другим перегруженным методом удаления в LinkedList является remove (int) или remove (Object), который удаляет Object или int, переданные как параметр. Этот метод пересекает LinkedList, пока не найдет объект и не отделит его от исходного списка. Следовательно, время выполнения этого метода равно O (n).

    В то время как метод ArrayList remove (int) включает в себя копирование элементов из старого массива в новый обновленный массив, следовательно, его время выполнения равно O (n).


3. Обратный итератор

LinkedList можно повторить в обратном направлении, используя descendingIterator(), а

в ArrayList отсутствует descendingIterator(), поэтому нам нужно написать собственный код для повторения по ArrayList в обратном направлении.


4. Начальная мощность

Если конструктор не перегружен, ArrayList создает пустой список начальной емкости 10, а

LinkedList только создает пустой список без начальной емкости.


5. Накладные расходы памяти

Накладные расходы памяти в LinkedList больше по сравнению с ArrayList, поскольку node в LinkedList должен поддерживать адреса следующих и предыдущих node. Пока

В ArrayList каждый индекс содержит только фактический объект (данные).


Источник

10
ответ дан Abhijeet Ashok Muneshwar 10 февр. '17 в 18:14
источник поделиться

В дополнение к другим хорошим аргументам, приведенным выше, вы должны заметить, что ArrayList реализует интерфейс RandomAccess, а LinkedList реализует Queue.
Так почему-то они затрагивают несколько разные проблемы, с разницей эффективности и поведения (см. Их список методов).

8
ответ дан PhiLho 27 нояб. '08 в 4:47
источник поделиться

Список массивов по существу представляет собой массив с методами для добавления элементов и т.д. (и вместо этого вы должны использовать общий список). Это набор элементов, к которым можно получить доступ с помощью индексатора (например, [0]). Это подразумевает переход от одного пункта к другому.

Связанный список указывает переход от одного элемента к другому (Item a → item b). Вы можете получить тот же эффект с помощью списка массивов, но связанный список абсолютно говорит, какой элемент должен следовать предыдущему.

5
ответ дан kemiller2002 20 апр. '10 в 18:32
источник поделиться

Это зависит от того, какие операции вы будете делать больше в списке.

ArrayList быстрее получает доступ к индексированному значению. Это намного хуже при вставке или удалении объектов.

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

4
ответ дан Matthew Schinckel 27 нояб. '08 в 4:42
источник поделиться

Важная особенность связанного списка (который я не читал в другом ответе) - это объединение двух списков. С массивом это O (n) (+ накладные расходы некоторых перераспределений) со связанным списком, это только O (1) или O (2); -)

Важно. Для Java LinkedList это неверно! См. Есть ли быстрый метод concat для связанного списка в Java?

4
ответ дан Karussell 23 марта '10 в 1:32
источник поделиться

Операция get (i) в ArrayList быстрее, чем LinkedList, потому что:
ArrayList: Реализуемая реализация интерфейса списка с разрешением resizeable LinkedList: Реализованная в двойном списке реализация интерфейсов List и Deque

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

4
ответ дан Amitābha 25 апр. '13 в 10:57
источник поделиться

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

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

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

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

4
ответ дан gaijinco 04 окт. '11 в 2:23
источник поделиться

ArrayList и LinkedList оба реализуют List interface, а их методы и результаты почти идентичны. Однако между ними есть несколько различий, которые делают лучше друг друга в зависимости от требования.

ArrayList Vs LinkedList

1) Search: ArrayList операция поиска довольно быстро по сравнению с операцией поиска LinkedList. get(int index) в ArrayList дает производительность O(1), тогда как LinkedList производительность O(n).

Reason: ArrayList поддерживает систему на основе индексов для своих элементов, поскольку она неявно использует структуру данных массива, что делает ее более быстрой для поиска элемента в списке. С другой стороны LinkedList реализует дважды связанный список, который требует обхода всех элементов для поиска элемента.

2) Deletion: LinkedList операция удаления дает O(1) производительность, а ArrayList дает переменную производительность: O(n) в худшем случае (при удалении первого элемента) и O(1) в лучшем случае (при удалении последнего элемента).

Вывод: удаление элемента LinkedList происходит быстрее по сравнению с ArrayList.

Причина: LinkedLists Каждый элемент поддерживает два указателя (адреса), который указывает на оба соседних элемента в списке. Следовательно, для удаления требуется только изменение местоположения указателя в двух соседних узлах (элементах) node, которые будут удалены. В то время как в ArrayList все элементы необходимо сдвинуть, чтобы заполнить пространство, созданное удаленным элементом.

3) Inserts Performance: LinkedList метод добавления дает O(1) производительность, а ArrayList дает O(n) в худшем случае. Причина та же, что и для удаления.

4) Memory Overhead: ArrayList поддерживает индексы и данные элемента, а LinkedList поддерживает данные элемента и два указателя для соседних узлов

следовательно, потребление памяти в LinkedList сравнительно велико.

Существует несколько сходств между этими классами:

  • Оба ArrayList и LinkedList - это реализация интерфейса List.
  • Оба они поддерживают порядок вставки элементов, что означает, что при отображении элементов ArrayList и LinkedList набор результатов будет иметь тот же порядок, в котором элементы были вставлены в список.
  • Оба этих класса не синхронизированы и могут быть синхронизированы явно с помощью метода Collections.synchronizedList.
  • iterator и listIterator, возвращаемые этими классами, являются fail-fast (если список структурно изменен в любое время после создания итератора, любым способом, кроме как с помощью методов удаления или добавления iterator’s, итератор будет throw a ConcurrentModificationException).

Когда использовать LinkedList и когда использовать ArrayList?

  • Как объяснялось выше, операции вставки и удаления дают хорошую производительность (O(1)) в LinkedList по сравнению с ArrayList(O(n)).

    Следовательно, если в приложении есть требование частого добавления и удаления, тогда LinkedList - лучший выбор.

  • Операции поиска (get method) выполняются быстро в Arraylist (O(1)), но не в LinkedList (O(n))

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

3
ответ дан Real73 02 нояб. '16 в 12:00
источник поделиться

ArrayList и LinkedList имеют свои плюсы и минусы.

ArrayList использует смежный адрес памяти по сравнению с LinkedList, который использует указатели на следующий node. Поэтому, когда вы хотите найти элемент в ArrayList быстрее, чем выполнять n итераций с помощью LinkedList.

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

Если в вашем приложении часто используются операции поиска, используйте ArrayList. Если у вас есть частая вставка и удаление, используйте LinkedList.

3
ответ дан Nesan Mano 15 мая '17 в 21:06
источник поделиться

ArrayList расширяет AbstractList и реализует интерфейс List. ArrayList - это динамический массив.
Можно сказать, что он был в основном создан для преодоления недостатков массивов

Класс LinkedList расширяет AbstractSequentialList и реализует интерфейс List, Deque и Queue.
Производительность
arraylist.get() - O (1), тогда как linkedlist.get() - O (n)
arraylist.add() - O (1) и linkedlist.add() равно 0 (1)
arraylist.contains() - O (n) и linkedlist.contains() равно O (n)
arraylist.next() - O (1), а linkedlist.next() - O (1)
arraylist.remove() - O (n), тогда как linkedlist.remove() - O (1)
В arraylist
iterator.remove() - O (n), в то время как In linkedlist - iterator.remove() - O (1)

0
ответ дан Randhawa 21 февр. '18 в 0:51
источник поделиться

Оба метода remove() и insert() имеют эффективность выполнения O (n) как для ArrayLists, так и для LinkedLists. Однако причина линейного времени обработки зависит от двух разных причин:

В ArrayList вы попадаете в элемент в O (1), но на самом деле удаление или вставка чего-то делает его O (n), потому что необходимо изменить все следующие элементы.

В LinkedList для фактического перехода к нужному элементу требуется O (n), потому что мы должны начинать с самого начала, пока не достигнем желаемого индекса. Фактически удаление или вставка является постоянным, потому что нам нужно только изменить 1 ссылку для remove() и 2 ссылки для insert().

Какая из двух быстрее для вставки и удаления зависит от того, где это происходит. Если мы ближе к началу, LinkedList будет быстрее, потому что нам нужно пройти через относительно немного элементов. Если мы ближе к концу, ArrayList будет быстрее, потому что мы доберемся туда в постоянное время и должны изменить только несколько оставшихся элементов, которые следуют за ним. Когда делается точно в середине, LinkedList будет быстрее, потому что переход через n элементов быстрее, чем перемещение n значений.

Бонус: Хотя нет способа сделать эти два метода O (1) для ArrayList, на самом деле есть способ сделать это в LinkedLists. Допустим, мы хотим пройти весь список, удалив и вставив элементы на нашем пути. Обычно вы начинаете с самого начала для каждого элемента с помощью LinkedList, мы также можем "сохранить" текущий элемент, с которым мы работаем с Iterator. С помощью Iterator мы получаем эффективность O (1) для remove() и insert() при работе в LinkedList. Являясь единственным преимуществом производительности, я знаю, где LinkedList всегда лучше, чем ArrayList.

0
ответ дан pietz 11 июня '16 в 23:40
источник поделиться

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

-1
ответ дан Ramakrishna 07 апр. '16 в 14:36
источник поделиться
  • 1
  • 2

Другие вопросы по меткам