JavaRush /Курсы /Java Syntax /ArrayList vs. LinkedList

ArrayList vs. LinkedList

Java Syntax
8 уровень , 5 лекция
Открыта

— Как насчёт немного размять мозги? Надеюсь, они ещё не закипели.

— В таблице контейнеров и коллекций ты ранее видел, что у одного и того же интерфейса может быть несколько реализаций. Сейчас я расскажу тебе, зачем это нужно. И в чем отличие ArrayList от LinkedList.

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

— Поэтому было решено сделать несколько реализаций одной и той же коллекции. И каждая реализация была оптимизирована для какого-то узкого набора операций. Так появились разные коллекции. Давай рассмотрим это на примере двух классов – ArrayList и LinkedList.

ArrayList vs. LinkedList - 1

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

LinkedList реализован внутри по-другому. Он реализован в виде связного списка: набора отдельных элементов, каждый из которых хранит ссылку на следующий и предыдущий элементы. Чтобы вставить элемент в середину такого списка, достаточно поменять ссылки его будущих соседей. А вот чтобы получить элемент с номером 130, нужно пройтись последовательно по всем объектам от 0 до 130. Другими словами операции set и get тут реализованы очень медленно. Посмотри на таблицу:

Описание Операция ArrayList LinkedList
Взятие элемента get Быстро Медленно
Присваивание элемента set Быстро Медленно
Добавление элемента add Быстро Быстро
Вставка элемента add(i, value) Медленно Быстро
Удаление элемента remove Медленно Быстро

— Ага. Кое-что начинает проясняться. А есть какие-нибудь критерии или правила, когда какая коллекция лучше?

— Ну, для простоты, я бы сформулировала такое правило: если ты собираешься вставлять (или удалять) в середину коллекции много элементов, то тебе лучше использовать LinkedList. Во всех остальных случаях – ArrayList.

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

Комментарии (170)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Rolik Уровень 41
20 марта 2023
LinkedList устарел.
la flacko flame Of Cactus Уровень 8
16 октября 2023
И есть кто помолодел?
Павел Соловьёв Уровень 16
2 мая 2022
У меня идея сломалась ?
Владік Уровень 41
8 июня 2022
Мало оперативки, нижний левый угол посмотри
Павел Соловьёв Уровень 16
15 июня 2022
От души !
Edward Northwind Уровень 37
27 апреля 2022
Я бы сказал, что Вставка скорее "Медленно" для каждой из коллекций. В случае массива - вам придутся двигать элементы, что не быстро, а в случае со списком - вам придется идти в эту середину перебором. Представьте, что у вас коллекция на 100К элементов и вам нужно добавить новый в середину. Удаление, опять же, "Быстро" только с краев (как и для массива при удаления в конце), по той же причине. Для Листа вообще манипуляции в середине крайне сомнительное решение, на основе чего бы он не был реализован. Тут почти для каждой операции можно добавить немаленькое такое "НО".
SWK Уровень 26
27 октября 2021
"Чтобы вставить элемент в середину такого списка, достаточно поменять ссылки его будущих соседей. А вот чтобы получить элемент с номером 130, нужно пройтись последовательно по всем объектам от 0 до 130. Другими словами операции set и get тут реализованы очень медленно. " Вообще-то, для того, чтобы вставить элемент после 130го, нужно сначала получить адрес 130го. А это, как мы поняли, у LinkedLista долго. Внимание вопрос: Точно ли вставка - быстрая, если перед ней долгий поиск?
Alexander Anopov Уровень 20
29 октября 2021
насколько понял вставка быстрая по сравнению с ArrayList, т.к. в LinkedList нужно выполнить "долгий" поиск и вставить элемент (поменять соседей), а в ArrayList поиск крайне быстрый, но чтобы вставить, например, на 1й индекс придется весь массив справа переместить, а это более затратно, чем просто поиск в LinkedList
SWK Уровень 26
1 ноября 2021
Фишка в том, что сферической вставки в вакууме не существует. Т.е., обычно, прежде, чем вставить, нужно найти место куда вставить. И это тоже отнимает время. Как оказалось, в лучших традициях JavaRush, дальше идёт другая статья, в которой разжёвывается подробно и оказывается, что всё не так, как рассказано в этой статье. Зачем так путать обучающихся - тайна покрытая мраком.
Ян Уровень 24
2 ноября 2021
А чтоб в ЛинкедЛист добавить элемент в самый конец не надо проходиться по всему?
SWK Уровень 26
3 ноября 2021
Чисто теоретически, последний могут и помнить. Именно для того, чтобы туда добавлять. Потому, что обычно именно туда добавляют. Т.е., добавление в самый конец максимально похоже на "сферическую вставку в вакууме".
Саша Уровень 11
9 октября 2021
Есть приложение ВТБ Бонус. Так вот, на примере этого приложения вы можете понять, как работает LinkedList. И хочется отметить, что это одна из наихудших реализаций в приложении, так как в связи с указанной структурой размещённых в нем данных, там невозможно найти то, что вы хотите, потому что поиск происходит по цепочке и ооооооочень долго. А иногда и вообще не находит то, что вы указали в поиске.
Евгений Уровень 27
2 октября 2021
добавление в ArrayList Быстро должно быть со звездочкой. Быстро* - если внутренний массив подошел к своей границе - и нужен массив побольше, то добавление - уже не быстро. (создать массив - скопировать - вставить) И еще. Допишите что ли что для LinkedList - найти куда вставить и вставить это 2 операции из таблицы Взятие элемента - get - медленно Вставка элемента - add(index, value) - быстро
Aleksandr Gorohov Уровень 28
8 сентября 2021
Вот отличная статья на хабре для знакомства со структурами данных.
Aleksey Erohovets Уровень 23
4 июля 2021
Что то не сильно понятно, допустим у меня лист на 1000 и я хочу каждый раз делать вставку в середину листа, с Arraylist все понятно надо будет каждый раз сдвигать пол массива но куда вставлять он находит моментыльно по индексу, с Linkedlist лист все иначе каждую вставку он начинает с начала листа потому как он не может сразу перейти на середину потому как не знает где это и соответственно тратит каждый раз время на нахождение середины листа, но зато быстро вставляет. Далеко не все однозначно. :)
Aleksey Erohovets Уровень 23
4 июля 2021
Моя логика говорит что он лучше только на вставку и удаление с начала листа, на этом все преимущества заканчиваются :)
25 октября 2022
Я подозреваю, что местА, куда нужно вставлять, то есть ссылки можно помнить где то отдельно, тогда и искать их не придется. Или, например, надо вставить в одно место сразу 100 элементов, которые представляют собой тоже связанный список, тогда поиск будет осуществляться 1 раз и одним чохом сразу 100 элементов вставили, поменяв только две ссылки. Пока у меня в голове примерно такая картина, посмотрю, что будет дальше.
Kuksh Уровень 15
10 апреля 2021
Можете разжевать логику добавления элемента в середину ArrayList и LinkedList? Про ArrayList я понял так - у каждого элемента есть свой индекс и когда нам надо вставить в середину, чтобы не было пробоя (null) мы сдвигаем всю правую часть на 1 элемент вперед и вставляем на освободившееся место - свой элемент. Про LinkedList не совсем понятно - написано, что Каждый элемент хранит ссылку на крайний элемент - то есть при списке 1-3-5-2-7 например элемент 5 знает об 3 и об 2, нам надо вставить допустим новый элемент 8 вместо числа 5 и какое преимущество нам дает, то, что 5 знает об 3 и 2? Если например за элементом 7 будет еще сотни элементов как и перед 1, то мы так же сдвигаем весь ряд вправо и в чем преимущество тогда? Вот этот момент не понял, что дает Наличие ссылки на соседние элементы, если нам все равно смещать ряд?
Людмила Уровень 20
10 апреля 2021
В том и весь фокус, что в LinkedList ничего не сдвигается: при добавлении элемента внутрь он получает ссылки на своих соседей, а соседи ссылку на него. Остальные элементы вообще не затрагиваются. Буквально лекцией выше была ссылка на хорошую статью о разнице в коллекциях и где их лучше применять: тыц
Kuksh Уровень 15
11 апреля 2021
О как, спасибо!) теперь ситуация прояснилась)
Vladimir Уровень 16
7 февраля 2021
LinkedList вообще зачем нужен? ну, ладно, в него я могу быстрее вставлять и удалять. принято. но я вот пытаюсь представить себе ситуацию в которой мне нужно что то вставлять и при этом не нужно это что то потом брать с того списка - и не получается. фантазия ржет, обзывается обидными словами и работать отказывается. может их конвертить один в другой надо? ну типа насовал в линкедлист 100500 чего то, потом раз - сделал из него аррайлист и пользуешься.
Valua Sinicyn Уровень 41
11 февраля 2021
Двусвязный список практически не используется. Но знать о нем нужно. В рамках Java API и для проформы. :)
Justinian Уровень 41 Master
19 апреля 2021

но я вот пытаюсь представить себе ситуацию в которой мне нужно что то вставлять и при этом не нужно это что то потом брать с того списка - и не получается.
если бы ты мог легко представлять такие ситуации, ты бы не изучал джаву здесь, а проводил бы где-то техсобесы или руководил бы разработкой. На этапе обучения нужно понимать инструменты, какие бывают, какие особенности. Когда дойдет дело до практики, тогда тебя уже будут учить что и когда и как лучше применять. Но чтобы дойти до этого момента, нужно чтобы у тебя была база. Чтобы ты мог сфокусироваться на более высокоуровневых вещах, а не на том, а что такое линкедлист в принципе и как он устроен. Вот для этого и нужна и теория и практическое понимание алгоритмов. Джава покрывает разные предметные области, если брать среднюю температуру по палате, самой популярной коллекцией наверное будет ArrayList и потом HashMap (который кстати под капотом содержит массив тех же связных списков). Достаточно редко будет требоваться действительно линкед лист, когда он понадобится, не пропустите. Но есть предметные области в которых специфические задачи, и там он будет требоваться больше. Это просто инструмент, это как на физкультуре, говорят прыгай, растягивайся, лезь на канат. Мало ведь кто интересуется "а когда мне это понадобится", зато когда действительно понадобится, то от соседской овчарки через забор перепрыгнуть как атлет, то залезть по простыням в женское общежитие на дерево за кошкой, когда надо, вы просто сами поймете и будете использовать эти инструменты. Поэтому,просто воспринимайте как есть, и держите глаза широко, кто как пишет, думайте как лучше на ваш взгляд. Все остальное потом подправят, расскажут, научат, поймете. Всему свое время.