← Назад к вопросам

Как определяется первый элемент в LinkedList

1.3 Junior🔥 131 комментариев
#Коллекции#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Как определяется первый элемент в LinkedList

LinkedList в Java — это двусвязный список (doubly-linked list), и первый элемент определяется специальной ссылкой (node reference). Рассмотрим детально, как это работает.

1. Структура LinkedList

Внутренняя структура Node

private static class Node<E> {
    E item;                    // Данные
    Node<E> next;             // Ссылка на следующий элемент
    Node<E> prev;             // Ссылка на предыдущий элемент
    
    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

Хранение ссылки на первый элемент

public class LinkedList<E> extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
    
    transient int size = 0;
    
    // Ссылка на первый элемент списка
    transient Node<E> first;
    
    // Ссылка на последний элемент списка
    transient Node<E> last;
}

Первый элемент хранится в переменной first, которая является ссылкой (reference) на объект типа Node<E>.

2. Как определить первый элемент - основные методы

getFirst() - O(1) сложность

public E getFirst() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}

Этот метод просто возвращает элемент, на который указывает ссылка first.

get(0) - O(1) сложность для первого элемента

public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
}

Node<E> node(int index) {
    // Для малых индексов идет от начала
    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        // Для больших индексов идет от конца
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

Для индекса 0 просто возвращает first.item без итерации.

peekFirst() - безопасная версия

public E peekFirst() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}

Отличие от getFirst() в том, что возвращает null вместо исключения.

3. Инициализация первого элемента

При добавлении в пустой список

public boolean add(E e) {
    linkLast(e);
    return true;
}

void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;  // Если список был пуст, newNode становится first
    else
        l.next = newNode;
    size++;
}

addFirst() - добавление в начало

public void addFirst(E e) {
    linkFirst(e);
}

private void linkFirst(E e) {
    final Node<E> f = first;
    final Node<E> newNode = new Node<>(null, e, f);
    first = newNode;  // Новый элемент становится first
    if (f == null)
        last = newNode;  // Если список был пуст
    else
        f.prev = newNode;  // Связываем старый first с новым
    size++;
}

4. Проверка наличия первого элемента

LinkedList<String> list = new LinkedList<>();

// Проверка пустоты
if (list.isEmpty()) {
    System.out.println("Список пуст");
} else {
    String first = list.getFirst();
}

// Безопасный способ
String first = list.peekFirst();
if (first != null) {
    System.out.println("Первый элемент: " + first);
}

5. Сравнение с ArrayList

ОперацияLinkedListArrayList
Получить первыйO(1)O(1)
Вставить в началоO(1)O(n)
Удалить первыйO(1)O(n)
Поиск по индексуO(n)O(1)

6. Практический пример

LinkedList<Integer> numbers = new LinkedList<>();
numbers.add(10);
numbers.add(20);
numbers.add(30);

// Все эти операции работают с first
Int first = numbers.getFirst();        // 10 - O(1)
int firstValue = numbers.get(0);       // 10 - O(1)
Int peekFirst = numbers.peekFirst();   // 10 - O(1)
Int poll = numbers.pollFirst();        // Удалить и вернуть first

// Добавить в начало
numbers.addFirst(5);                   // first теперь указывает на 5

7. Внутренние детали реализации

Временные сложности

// O(1) операции - прямой доступ к first
getFirst()          // Прямой доступ к first.item
addFirst()          // Создание нового node, обновление first
pollFirst()         // Удаление first, обновление ссылок
peekFirst()         // Проверка first == null

// O(n) операции - требуют итерации
get(i) где i > 0    // Нужно пройти i узлов от first
remove(i) где i > 0 // Нужно найти node(i)

Заключение

Первый элемент в LinkedList определяется через приватную переменную first типа Node<E>. Это позволяет получать, добавлять и удалять первый элемент с временной сложностью O(1). LinkedList идеален для операций с началом/концом списка, но плохо подходит для доступа по индексу в середине списка.

Как определяется первый элемент в LinkedList | PrepBro