Исследовать различия в изучении LinkedList и ArrayList

LinkedList и ArrayList

Содержание статьи есть какие - либо вопросы , пожалуйста , обращайтесь к обсуждению (просьба указать причину)
почта: [email protected]
микро письмо: вводный-wgh0807
QQ: 490 536 401

Некоторое время назад, я использовал , чтобы написать советы по поиску ES на основе было установлено, что проблемы, взглянуть на код , чтобы устранить проблему вовремя босса, вдруг задать мне вопрос: «Почему вы используете LinkedList используется для вставки и удаления его или рассмотреть эффективность ??? "
этот вопрос мое сердце начало, ответ , потому что считается вставки и делеции эффективность. То , что босс не сказал , как, просто скажите мне позже внимание. Наконец, расследование проблемы , и это имеет ничего общего.

Тем не менее, этот вопрос всегда был парящий в моей голове - почему я использовал LinkedList?

Университет первый контакт C, то C ++, то есть Java и Python. В C / C ++ повседневной практике, наиболее часто используется массив, C / C ++ массив не представляется возможным расширение, поэтому при обучении к указателю, как если бы я открыл дверь в новый мир, часто пишется список сами вместо более сложного массива ,
Позже я связался с Java, контакт с коллекцией Явы оказался в Новом Свете, в системе при условии свободного расширения списка. Относительное расширение ArrayList потребности за кулисы, я больше итальянский язык в LinkedList, с течением времени, чтобы привыкнуть к LinkedList.

Таким образом, вопрос, почему вы всегда использовать меньше продукта LinkedList Ассамблея призвала этот новый мир из него?

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

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

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

Конечно, существуют определенные различия в двух. ArrayList упоминается в документе:

size, isEmpty, get, set, iterator, И listIteratorоперации выполняются в постоянная время. addОперация выполняется в амортизационном постоянная время, то есть, при добавлении п элементов требует O (N) времени. Все остальные операции выполняются в линейном времени (грубо говоря). Постоянный фактор является низким по сравнению с , что для LinkedListреализации.

Отличающееся тем, что опорный, размер, IsEmpty, получить, установить, итератор и ArrayList ListIterator Времени работы сложность O (1), увеличивая цель (надстройки) сложность времени О (п), в соответствии с временной сложностью удаляются нижний индекс O (N ^ 2).

Для LinkedList, временная сложность добавления, размера, метод IsEmpty, ListIterator представляет собой О (1), множестве, получает, в соответствии со способом удаления сложности времени индекса O (N).

以上算法都没有考虑常数、系数,以ArrayList的下标删除为例,应该为n^2/2

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

Базовая структура хранения

LinkedList структура хранения:

Структура хранения LinkedList

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

LinkedList в памяти для хранения:

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

Тем не менее, предыдущий и следующий являются узел <E> типа, и нет указателя Java это? ?

Они должны быть в памяти надолго на этом пути? ?

Идеально сохраняются в формате памяти

Следует учитывать памяти для хранения фактов в виде Java, есть стек, куча, постоянный бассейн. , ,

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

Визуально это.

ArrayList, структура хранения:

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

Просмотреть общий метод, рекомендованный здесь два класса базовой реализации, мы попытались сделать кинофильм усталым. , ,

Экспериментальное сравнение

Эксперимент Код

Код эксперимента GitHub, приветствовал предложенные поправки. https://github.com/wgh0807/experiment/blob/master/src/test1906/test1.java

Экспериментальная среда

Платформа: Mac OSX 10.14.5

Java версия: 1.8.0_131

Экспериментальный дизайн

Экспериментальный объем данных составляет один миллион целочисленных данных (1-1000000). Три темы: параметры по умолчанию LinkedList, параметры инициализации для одного миллиона ArrayList и нет параметров ArrayList.

Каждый объект отдельно проверить время, необходимое для выполнения следующих функций:

  1. Создать миллион раз время, необходимое для объекта
  2. Последовательная увеличивает один миллион данных, используемых время
  3. Случайное чтение времени нужно потреблять одну тысячу
  4. Одна тысячи случайной информации обновления данных со временем
  5. Перед удалением одной тысячи данных по времени
  6. Удалить последние тысячи данных по времени
  7. Удалить тысячи случайных данных, используемое время

Экспериментальные результаты

Вслед за LinkedList параметров по умолчанию, параметры 1000000 (один миллион), а также параметры по умолчанию ArrayList ArrayList. Эксперименты показывают время в миллисекундах. Результаты затрагиваемых систем, распределение ресурсов и другие факторы, результаты могут быть неустойчивыми, этим экспериментом, используя только результаты запуска в то же время для сравнения. Же прогон результатов может быть также с учетом вышеуказанных факторов, но влияние ограничено, этот тест можно пренебречь.

根据实验结果我们可以看到:

  1. 创建一百万次对象而言,有/无参数的ArrayList时间消耗极大。
  2. 顺序增加而言,总体上LinkedList表现较为优异。
  3. 随机读取而言,LinkedList时间消耗较大,不明显。
  4. 随机更新而言,LinkedList时间消耗极大
  5. 删除前一千条数据,两项ArrayList时间消耗极大
  6. 删除最后一千条数据,三项结果无明显差异
  7. 随机删除而言,LinkedList时间消耗极大

结果解释

  1. 查看构造方法。发现LinkedList方法体为空;无参ArrayList构造对内部数组进行了初始化;整型参数ArrayList构造方法对传入参数进行了合法性判断,之后对数组进行初始化。由于ArrayList逻辑较为复杂,所以时间耗费最大。
  2. 查看顺序增加方法(add(E e))。对于LinkedList,add模块的代码量共14行,直接获取了最后一个元素,给其增加下一个节点。而ArrayList的add功能先进行了数组扩容检查,如果需要扩容则进行数组复制,代码量较大。这就是时间花销LinkedList<有参ArrayList< 无参ArrayList 的原因。
  3. 查看其get(int index)方法。LinkedList先判断下标是否存在,然后判断位置距离开始节点近还是结束节点近,之后使用for循环获取目标对象并获取值(item)。ArrayList中,首先判断下标是否存在,存在即以数组的形式访问,节省了很多时间。
  4. 查看set(int index)方法,这个方法的差距和3中相同,主要存在于获取目的节点。LinkedList使用了for循环,ArraysLink使用数组访问方式,ArraysLink在随机访问时(尤其是靠近中间值)效率会明显优于LinkedList。
  5. 删除前一千条数据需要查看remove(int index),在两端删除对于LinkedList影响较小;但是对于ArrayList来说,虽然查找对象较快,但是需要将后续节点向前紧缩,需要新建数组对象并使用copy方法对其赋值,造成了时间消耗极大的结果。
  6. 删除前一千条数据需要查看remove(int index),在两端删除对于LinkedList影响较小;对于ArrayList来说,删除尾部对象也不需要重新构建数组,所以没有明显差距。
  7. 随机删除需要查看remove(int index)方法,LinkedList和ArrayList差距主要还是在于查找对象。找到对象后删除的方法相对而言ArrayList简单一些,所以ArrayList速率会更快一些。

总结

时间方面

LinkedList 优势在于灵活可变,但是随机行为对其影响较大,需要执行for循环。虽然底层已经做了一次折半查找,但是还是比不上直接从数组获取。利用其灵活的特点,在增加、删除(除最后元素外的删除)操作时表现良好,但是对于获取系列操作(尤其是获取1/4和3/4区域数据)时较为缓慢。

ArrayList优势在于稳定连续,底层使用数组实现使得随机行为得到很好的支持。但是对于破坏其稳定性的行为,如增加、删除操作,对其影响较大。删除操作的影响和其删除元素的位置有关,如果是在最后,则压力较小,只需要置空即可;如果在中间或者前部,则需要使用copy方法,将剩余元素重新组建成为一个新的数组。增加操作则需要判断是否超过现有数组长度,如果超过则需要定义新的较长数组并将当前数组的值拷贝到新的数组中再执行设置值的操作。

空间方面

LinkedList结构较大,并且用的变量较多,较为占用空间。

ArrayList结构无参默认结构简单,空间较小,使用多为常量,占用空间较小

日常使用

日常更多的使用ArrayList,性价比更高。但是对于增删操作较为集中的情况中,可以选用LinkedList。同时需要注意,链表删除不一定比数组快,需要根据实际情况进行判断。

Спасибо за чтение, например, текст у вас есть вопросы, предложения, пожалуйста , обсудите
Написанный wgh0807

рекомендация

отwww.cnblogs.com/wgh0807/p/11201739.html