LinkedList

LinkedList — класс из пакета java.util, реализующий двусвязный список. Каждый элемент хранится в отдельном узле, который содержит ссылки на предыдущий и следующий узлы. LinkedList одновременно реализует интерфейсы List, Deque и Queue, поэтому может использоваться как обычный список, двусторонняя очередь или стек.

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

Зачем нужен

  • Когда нужно часто вставлять и удалять элементы в начале или в середине последовательности.

  • Когда коллекция должна работать как очередь FIFO или как двусторонняя очередь (Deque).

  • Когда важна семантика «head/tail» — например, буфер команд, история действий, очередь сообщений.

Конструкторы

  • LinkedList() — пустой список.

  • LinkedList(Collection<? extends E> c) — список с элементами из другой коллекции, в её порядке итерации.

Популярные методы

Из List:

  • add(E e), add(int index, E e) — добавить элемент.

  • get(int index), set(int index, E e), remove(int index).

  • size(), contains(Object o), indexOf(Object o).

Из Deque / Queue:

  • addFirst(E e) / addLast(E e) — добавить в начало/конец.

  • getFirst() / getLast() — посмотреть, не извлекая (бросает исключение, если пусто).

  • peekFirst() / peekLast() — посмотреть, null если пусто.

  • removeFirst() / removeLast() — удалить и вернуть.

  • pollFirst() / pollLast() — удалить и вернуть, null если пусто.

  • offer(E e), poll(), peek() — методы очереди.

  • push(E e) / pop() — стек поверх Deque.

Пример 1. Базовое использование как списка

import java.util.LinkedList;

public class BasicList {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("Arduino");
        list.add("ESP32");
        list.add("Raspberry Pi");

        System.out.println(list);
        System.out.println("Размер: " + list.size());
        System.out.println("Второй: " + list.get(1));
    }
}

Вывод:

[Arduino, ESP32, Raspberry Pi]
Размер: 3
Второй: ESP32

Пример 2. Добавление в начало и конец

import java.util.LinkedList;

public class FirstLast {
    public static void main(String[] args) {
        LinkedList<Integer> q = new LinkedList<>();
        q.addLast(2);
        q.addLast(3);
        q.addFirst(1);
        q.addLast(4);
        System.out.println(q);
    }
}

Вывод:

[1, 2, 3, 4]

Пример 3. LinkedList как очередь (FIFO)

import java.util.LinkedList;
import java.util.Queue;

public class FifoQueue {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();
        queue.offer("cmd1");
        queue.offer("cmd2");
        queue.offer("cmd3");

        while (!queue.isEmpty()) {
            System.out.println("Обработка: " + queue.poll());
        }
    }
}

Вывод:

Обработка: cmd1
Обработка: cmd2
Обработка: cmd3

Пример 4. LinkedList как стек (LIFO)

import java.util.LinkedList;

public class StackUsage {
    public static void main(String[] args) {
        LinkedList<String> stack = new LinkedList<>();
        stack.push("A");
        stack.push("B");
        stack.push("C");

        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }
}

Вывод:

C
B
A

Пример 5. Удаление по индексу и по значению

import java.util.LinkedList;

public class Remove {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("red");
        list.add("green");
        list.add("blue");
        list.add("green");

        list.remove(0);
        System.out.println(list);
        list.remove("green");
        System.out.println(list);
    }
}

Вывод:

[green, blue, green]
[blue, green]

Пример 6. Итерация

import java.util.LinkedList;

public class Iterate {
    public static void main(String[] args) {
        LinkedList<Integer> nums = new LinkedList<>();
        for (int i = 1; i <= 4; i++) nums.add(i * 10);

        int sum = 0;
        for (int n : nums) sum += n;
        System.out.println("Сумма: " + sum);
    }
}

Вывод:

Сумма: 100

Пример 7. Очередь сенсорных данных Robot Phobo

import java.util.LinkedList;

public class SensorBuffer {
    public static void main(String[] args) {
        LinkedList<Integer> buffer = new LinkedList<>();
        int[] readings = {10, 12, 15, 18, 20, 22};

        int window = 3;
        for (int v : readings) {
            buffer.addLast(v);
            if (buffer.size() > window) buffer.removeFirst();

            int sum = 0;
            for (int x : buffer) sum += x;
            double avg = (double) sum / buffer.size();
            System.out.println("Окно " + buffer + " avg=" + avg);
        }
    }
}

Вывод:

Окно [10] avg=10.0
Окно [10, 12] avg=11.0
Окно [10, 12, 15] avg=12.333333333333334
Окно [12, 15, 18] avg=15.0
Окно [15, 18, 20] avg=17.666666666666668
Окно [18, 20, 22] avg=20.0

Пример 8. peek vs get на пустом списке

import java.util.LinkedList;

public class PeekEmpty {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        System.out.println("peek: " + list.peek());
        try {
            list.getFirst();
        } catch (Exception e) {
            System.out.println("getFirst бросил: " + e.getClass().getSimpleName());
        }
    }
}

Вывод:

peek: null
getFirst бросил: NoSuchElementException

См. также

Примечание

Описание основано на официальной документации Oracle Java SE 21 API (https://docs.oracle.com/en/java/javase/21/docs/api/). Материал распространяется на условиях Oracle Free Documentation License. Тексты статьи написаны редакцией AlashEd своими словами; примеры кода — авторские.