Java LinkedList

本文深入解析了LinkedList的迭代器实现原理,介绍了其内部类ListItr的具体实现细节,包括节点结构、迭代操作如hasNext、next及remove等,并探讨了与ArrayList迭代器的不同之处。
List接口有两个实现,一个是ArrayList,另一个是LinkedList。从字面上就可以看出Array表示 的是数组,Link表示的是链表,区别一目了然,今天看看LinkedList的迭代器的实现。

节点定义:

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;
}
}


典型的链表节点结构啊!

ArrayList中可以通过iterator来获取迭代器,很可惜的告诉你,LinkedList中没有。它的基础就是listIterator。


public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}


果不其然,又是一个内部类了。


private class ListItr implements ListIterator<E> {
private Node<E> lastReturned = null;
private Node<E> next;
private int nextIndex;
private int expectedModCount = modCount;

ListItr(int index) {
// assert isPositionIndex(index);
next = (index == size) ? null : node(index);
nextIndex = index;
}

public boolean hasNext() {
return nextIndex < size;
}

public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();

lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}

public boolean hasPrevious() {
return nextIndex > 0;
}

public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();

lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}

public int nextIndex() {
return nextIndex;
}

public int previousIndex() {
return nextIndex - 1;
}

public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();

Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}

public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}

public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}


代码其实也很简单,就是指针呗。
### Java 中 `LinkedList` 的用法及相关信息 #### 1. 基本概念 `LinkedList` 是 Java 集合框架中的一个重要实现类,它实现了 `List` 接口和 `Deque` (双端队列)接口。与数组列表不同,链表通过节点链接来存储元素[^1]。 #### 2. 创建 `LinkedList` 可以使用默认构造函数创建一个空的 `LinkedList` 实例: ```java import java.util.LinkedList; // Create an empty linked list LinkedList<String> linkedList = new LinkedList<>(); ``` 也可以基于现有集合初始化一个新的 `LinkedList`: ```java import java.util.Arrays; import java.util.LinkedList; // Initialize with existing elements from another collection LinkedList<Integer> numbers = new LinkedList<>(Arrays.asList(1, 2, 3)); ``` #### 3. 添加元素 向 `LinkedList` 插入新项非常灵活,支持多种方式: - 使用 `add(E e)` 方法在列表末尾追加元素; - 利用 `offerFirst(E e)` 或者 `push(E e)` 将对象放置于头部位置; - 调用 `offerLast(E e)` 把数据添加到尾部; 示例如下所示: ```java linkedList.add("first"); linkedList.offerFirst("second"); // Add at the beginning linkedList.push("third"); // Also adds at the start linkedList.offerLast("fourth"); // Adds element at end of queue ``` #### 4. 访问元素 由于 `LinkedList` 同时具备双向迭代特性以及随机访问能力,因此提供了丰富的检索手段: - 获取第一个/最后一个元素:`getFirst()`, `getLast()`; - 查看但不移除头指针所指向的对象:`peek()`, `peekFirst()`, `peekLast()`; - 移动并返回首个匹配项的位置:`indexOf(Object o)`; 具体操作如下: ```java System.out.println(linkedList.getFirst()); // Prints "third" System.out.println(linkedList.peekLast()); // Outputs "fourth" int index = linkedList.indexOf("first"); // Returns position where found or -1 otherwise ``` #### 5. 删除元素 删除功能同样强大而多样: - 清理整个容器的内容:`clear()`; - 取消指定索引处的数据记录:`remove(int index)`; - 弹出栈顶元素(即最先进来的那个):`pop()`; - 自定义条件下的批量清除动作:`removeIf(Predicate<? super E> filter)`; 实际应用例子: ```java linkedList.pop(); // Removes topmost item ("third") linkedList.remove(0); // Deletes entry located at given offset linkedList.removeIf(s -> s.equals("second")); // Filters out all occurrences matching predicate expression ``` #### 6. 特殊用途方法 除了上述常规 API 外,还有几个专用于处理特定场景的方法值得提及: - **反转顺序**:调用 `descendingIterator()` 返回逆序遍历器实例; - **转换成数组形式**:借助 `toArray(T[] a)` 函数可方便地把内部结构映射至目标类型的一维数组上; 代码片段展示这些特性的运用: ```java for(String str : linkedList.descendingIterator()){ System.out.print(str + ", "); } String[] arrayForm = linkedList.toArray(new String[linkedList.size()]); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值