1. введение
Связанный список -это реализация двусвязного списка интерфейсов List и Deque . Он реализует все необязательные операции со списком и разрешает все элементы (включая null ).
2. Особенности
Ниже вы можете найти наиболее важные свойства Связанного списка :
- Операции, индексирующие список, будут проходить по списку от начала или до конца, в зависимости от того, что ближе к указанному индексу
- Это не синхронизировано
- Его Итератор и ListIterator итераторы быстры к сбою (это означает, что после создания итератора, если список будет изменен, будет выдано исключение ConcurrentModificationException )
- Каждый элемент является узлом, который хранит ссылку на следующий и предыдущий
- Он поддерживает порядок вставки
Хотя Связанный список не синхронизирован, мы можем получить его синхронизированную версию, вызвав коллекции .Метод synchronizedList , например:
List list = Collections.synchronizedList(new LinkedList(...));
3. Сравнение с ArrayList
Хотя оба они реализуют интерфейс List , они имеют различную семантику, что, безусловно, повлияет на решение о том, какой из них использовать.
3.1. Структура
ArrayList – это структура данных на основе индекса, поддерживаемая Массивом . Он обеспечивает произвольный доступ к своим элементам с производительностью, равной O(1).
С другой стороны, Связанный список хранит свои данные в виде списка элементов, и каждый элемент связан со своим предыдущим и следующим элементом. В этом случае операция поиска элемента имеет время выполнения, равное O(n).
3.2. Операции
Операции вставки, добавления и удаления элемента выполняются быстрее в LinkedList , поскольку нет необходимости изменять размер массива или обновлять индекс при добавлении элемента в произвольную позицию внутри коллекции, изменяются только ссылки в окружающих элементах.
3.3. Использование памяти
Связанный список потребляет больше памяти, чем ArrayList , потому что каждый узел в Связанном списке хранит две ссылки, одну для своего предыдущего элемента и одну для следующего элемента, в то время как ArrayList содержит только данные и его индекс.
4. Использование
Вот несколько примеров кода, которые показывают, как вы можете использовать Связанный список :
4.1. Создание
LinkedList
4.2. Добавление элемента
LinkedList реализует List и Deque интерфейс, помимо стандартных add() и addAll() методов, которые вы можете найти addFirst() и addLast() , которые добавляют элемент в начале или в конце соответственно.
4.3. Удаление элемента
Аналогично добавлению элементов, реализация этого списка предлагает remove First() и removeLast().
Кроме того, существует удобный метод remove First Occurrence() и removelastoccurrence () , который возвращает логическое значение (true, если коллекция содержала указанный элемент).
4.4. Операции с очередями
Deque интерфейс обеспечивает поведение, подобное очереди (на самом деле Deque расширяет Очередь интерфейс):
linkedList.poll(); linkedList.pop();
Эти методы извлекают первый элемент и удаляют его из списка.
Разница между poll() и pop() заключается в том, что pop вызовет NoSuchElementException() в пустом списке, тогда как poll возвращает null. Также доступны API poll First() и pollLast () .
Вот, например, как работает API push :
linkedList.push(Object o);
Который вставляет элемент в качестве главы коллекции.
Связанный список имеет много других методов, большинство из которых должны быть знакомы пользователю, который уже использовал Списки . Другие, предоставляемые Deque , могут быть удобной альтернативой “стандартным” методам.
Полную документацию можно найти здесь .
5. Заключение
ArrayList обычно является реализацией по умолчанию List .
Однако существуют определенные случаи использования, в которых использование Связанного списка будет более подходящим, например, предпочтения для постоянного времени вставки/удаления (например, частые вставки/удаления/обновления), по сравнению с постоянным временем доступа и эффективным использованием памяти.
Примеры кода можно найти на GitHub .