← Назад к вопросам
Как можно обратиться на предыдущий элемент в LinkedList?
1.3 Junior🔥 211 комментариев
#Коллекции#ООП#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как обратиться на предыдущий элемент в LinkedList
LinkedList в Java — это двусвязный список (doubly-linked list), где каждый элемент имеет ссылку на следующий и предыдущий элемент. Существует несколько способов получить доступ к предыдущему элементу.
1. Использование ListIterator
Наиболее универсальный способ — это использование ListIterator, который поддерживает движение в обе стороны:
LinkedList<String> list = new LinkedList<>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
ListIterator<String> iterator = list.listIterator(2); // Начинаем с индекса 2
while (iterator.hasNext()) {
System.out.println("Forward: " + iterator.next());
}
while (iterator.hasPrevious()) {
System.out.println("Backward: " + iterator.previous());
}
Вывод:
Forward: C
Forward: D
Backward: D
Backward: C
Backward: B
Backward: A
2. Методы ListIterator
ListIterator<Integer> it = list.listIterator(2);
// Проверка наличия следующего элемента
if (it.hasNext()) {
int next = it.next(); // Получить следующий и переместить курсор
}
// Проверка наличия предыдущего элемента
if (it.hasPrevious()) {
int prev = it.previous(); // Получить предыдущий и переместить курсор
}
// Получить индекс
int nextIndex = it.nextIndex(); // индекс следующего
int previousIndex = it.previousIndex(); // индекс предыдущего
3. Пример с условием на предыдущий элемент
LinkedList<String> list = new LinkedList<>(Arrays.asList("A", "B", "C", "D", "E"));
ListIterator<String> iterator = list.listIterator(3);
while (iterator.hasPrevious()) {
String previous = iterator.previous();
System.out.println(previous);
// Если нашли нужный элемент, вставим что-нибудь
if (previous.equals("B")) {
iterator.add("B1");
}
}
4. Навигация по списку в обе стороны
public static void bidirectionalTraversal(LinkedList<String> list) {
ListIterator<String> it = list.listIterator(list.size() / 2);
// Сначала вперёд
System.out.println("Forward from middle:");
while (it.hasNext()) {
System.out.println(it.next());
}
// Потом назад
System.out.println("Backward to start:");
while (it.hasPrevious()) {
System.out.println(it.previous());
}
}
5. Почему нельзя с обычным Iterator?
// ❌ Это не работает - Iterator не поддерживает hasPrevious()
Iterator<String> it = list.iterator();
// it.hasPrevious(); // Ошибка компиляции!
// it.previous(); // Ошибка компиляции!
// ✅ Нужно использовать ListIterator
ListIterator<String> listIt = list.listIterator();
listIt.hasPrevious(); // Правильно
listIt.previous(); // Правильно
6. Удаление и изменение через ListIterator
LinkedList<String> list = new LinkedList<>(Arrays.asList("A", "B", "C", "D"));
ListIterator<String> it = list.listIterator(2); // Начинаем с C
it.next(); // Переместимся на D
it.remove(); // Удалим D
it.previous(); // Вернёмся на C
it.set("C_modified"); // Заменим C
it.add("X"); // Вставим X после текущей позиции
System.out.println(list); // [A, B, C_modified, X]
7. Поиск и получение соседних элементов
public class ListHelper {
public static <T> T getPrevious(LinkedList<T> list, T element) {
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
if (it.next().equals(element)) {
if (it.hasPrevious()) {
it.previous(); // Вернёмся на текущий
it.previous(); // Перейдём на предыдущий
return it.next(); // Получим предыдущий и переместимся на него
}
}
}
return null;
}
public static <T> T getNext(LinkedList<T> list, T element) {
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
if (it.next().equals(element)) {
if (it.hasNext()) {
return it.next();
}
}
}
return null;
}
}
// Использование
LinkedList<String> list = new LinkedList<>(Arrays.asList("A", "B", "C", "D"));
String prev = ListHelper.getPrevious(list, "C"); // Вернёт "B"
String next = ListHelper.getNext(list, "C"); // Вернёт "D"
8. Сравнение подходов
LinkedList<Integer> list = new LinkedList<>(Arrays.asList(1, 2, 3, 4, 5));
// ❌ Неэффективно - итерирует по каждому элементу
int index = 2;
Integer prev1 = list.get(index - 1); // O(n) для LinkedList!
// ✅ Эффективно - использует итератор
ListIterator<Integer> it = list.listIterator(index);
it.next(); // Переместимся на нужный элемент
it.previous(); // Вернёмся на предыдущий
it.previous(); // Получим предыдущий
Integer prev2 = it.next(); // Получим значение
9. Практический пример: проверка отсортированного списка
public static <T extends Comparable<T>> boolean isSorted(LinkedList<T> list) {
ListIterator<T> it = list.listIterator(1);
while (it.hasNext()) {
T current = it.next();
T previous = list.get(it.previousIndex() - 1);
if (previous.compareTo(current) > 0) {
return false; // Нарушение порядка
}
}
return true;
}
10. Полный пример: двусвязный обход
public class LinkedListNavigator {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>(Arrays.asList("A", "B", "C", "D", "E"));
ListIterator<String> it = list.listIterator(2);
System.out.println("Starting at index 2 (C)");
// Несколько раз вперёд
for (int i = 0; i < 2 && it.hasNext(); i++) {
System.out.println("Next: " + it.next());
}
// Несколько раз назад
for (int i = 0; i < 3 && it.hasPrevious(); i++) {
System.out.println("Previous: " + it.previous());
}
// Текущая позиция
System.out.println("Current next index: " + it.nextIndex());
System.out.println("Current previous index: " + it.previousIndex());
}
}
Ключевые выводы
- Используй ListIterator — это основной способ доступа к предыдущему элементу
- Отличие от Iterator — ListIterator добавляет методы hasPrevious(), previous(), set(), add()
- Производительность — в LinkedList использование итератора эффективнее, чем get(index)
- Двусвязный список — LinkedList позволяет эффективно двигаться в обе стороны
- Модификация — можно удалять и добавлять элементы через итератор
Этот подход даёт максимальную гибкость при работе со списками в Java.