在线工具站
- 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。
程序员资料站
- 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程、各大面试专题,还有常用开发工具的教程。
小报童专栏精选Top100
- 推荐一个小报童专栏导航站:小报童精选Top100(http://xbt100.top),收录了生财有术项目精选、AI海外赚钱、纯银的产品分析等专栏,陆续会收录更多的专栏,欢迎体验~
LinkedList
是 Java 集合框架中一个重要的类,提供了链表数据结构的实现。它既可以作为列表使用,也可以作为队列和双端队列使用。
1. LinkedList
类概述
1.1 定义
LinkedList
类位于 java.util
包中,是 List
接口的一个实现类,同时实现了 Deque
接口,这意味着它既可以用作列表,也可以用作双端队列。
public class LinkedList<E> extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, Serializable {
// 构造方法和主要方法省略
}
1.2 主要特点
- 双向链表:
LinkedList
使用双向链表存储元素,这使得插入和删除操作非常高效。 - 有序性:
LinkedList
保持元素的插入顺序。 - 双端队列:
LinkedList
实现了Deque
接口,可以在两端进行插入和删除操作。
2. 常用方法
2.1 构造方法
LinkedList
提供了多种构造方法,用于创建不同类型的列表。
// 创建一个空的 LinkedList
LinkedList<E> list = new LinkedList<>();
// 创建一个包含指定集合的 LinkedList
LinkedList<E> list = new LinkedList<>(Collection<? extends E> c);
2.2 add
方法
add
方法用于将指定的元素添加到列表的末尾。
public boolean add(E e)
示例
LinkedList<String> list = new LinkedList<>();
list.add("Alice");
list.add("Bob");
System.out.println(list); // 输出:[Alice, Bob]
2.3 addFirst
和 addLast
方法
addFirst
和 addLast
方法分别用于将指定的元素添加到列表的开头和末尾。
public void addFirst(E e)
public void addLast(E e)
示例
list.addFirst("Charlie");
System.out.println(list); // 输出:[Charlie, Alice, Bob]
list.addLast("David");
System.out.println(list); // 输出:[Charlie, Alice, Bob, David]
2.4 remove
方法
remove
方法用于从列表中移除指定的元素。
public boolean remove(Object o)
示例
list.remove("Alice");
System.out.println(list); // 输出:[Charlie, Bob, David]
2.5 removeFirst
和 removeLast
方法
removeFirst
和 removeLast
方法分别用于移除并返回列表的第一个和最后一个元素。
public E removeFirst()
public E removeLast()
示例
String firstElement = list.removeFirst();
System.out.println(firstElement); // 输出:Charlie
System.out.println(list); // 输出:[Bob, David]
String lastElement = list.removeLast();
System.out.println(lastElement); // 输出:David
System.out.println(list); // 输出:[Bob]
2.6 get
方法
get
方法用于获取指定位置的元素。
public E get(int index)
示例
String element = list.get(0);
System.out.println(element); // 输出:Bob
2.7 size
方法
size
方法用于获取列表中的元素数量。
public int size()
示例
int size = list.size();
System.out.println("Size: " + size); // 输出:1
2.8 迭代器
LinkedList
提供了 iterator
方法用于获取列表的迭代器,以便按顺序遍历元素。
public Iterator<E> iterator()
示例
list.add("Alice");
list.add("Bob");
list.add("Charlie");
for (String element : list) {
System.out.println("Element: " + element);
}
// 输出顺序为:
// Element: Alice
// Element: Bob
// Element: Charlie
3. 内部实现原理
LinkedList
的内部实现基于双向链表,这使得它在插入和删除操作上具有很高的效率,但在随机访问元素时性能较低。
3.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;
}
}
3.2 链表操作
- 插入操作:在插入元素时,
LinkedList
创建一个新的节点,并调整相邻节点的引用,以将新节点链接到链表中。 - 删除操作:在删除元素时,
LinkedList
调整相邻节点的引用,以将目标节点从链表中移除。 - 访问操作:在访问指定位置的元素时,
LinkedList
通过遍历链表找到目标节点。
3.3 性能分析
由于双向链表的结构,LinkedList
在插入和删除操作上具有 O(1) 的时间复杂度,而在随机访问元素时具有 O(n) 的时间复杂度。
4. 实际应用
4.1 基本用法
LinkedList
最常见的应用场景是需要频繁插入和删除元素的列表。
示例
LinkedList<String> list = new LinkedList<>();
list.add("Alice");
list.add("Bob");
list.add("Charlie");
list.remove("Alice");
list.addFirst("David");
list.addLast("Eve");
for (String element : list) {
System.out.println("Element: " + element);
}
// 输出顺序为:
// Element: David
// Element: Bob
// Element: Charlie
// Element: Eve
4.2 实现队列
LinkedList
可以用于实现队列,利用 addLast
和 removeFirst
方法来分别插入和移除元素。
示例
LinkedList<String> queue = new LinkedList<>();
queue.addLast("Alice");
queue.addLast("Bob");
queue.addLast("Charlie");
String firstInQueue = queue.removeFirst();
System.out.println(firstInQueue); // 输出:Alice
4.3 实现双端队列
LinkedList
实现了 Deque
接口,可以在两端进行插入和删除操作,适用于需要双端操作的场景。
示例
LinkedList<String> deque = new LinkedList<>();
deque.addFirst("Alice");
deque.addLast("Bob");
deque.addFirst("Charlie");
String firstElement = deque.removeFirst();
System.out.println(firstElement); // 输出:Charlie
String lastElement = deque.removeLast();
System.out.println(lastElement); // 输出:Bob
5. 性能考虑
在使用 LinkedList
时,需要注意以下几点:
- 插入和删除操作:
LinkedList
在插入和删除操作上具有 O(1) 的时间复杂度,非常适合频繁插入和删除元素的场景。 - 随机访问操作:由于链表结构的特点,
LinkedList
在随机访问元素时性能较低,具有 O(n) 的时间复杂度。 - 空间开销:每个节点都包含指向前后节点的引用,因此
LinkedList
比ArrayList
具有更高的空间开销。
6. 扩展阅读
6.1 ArrayList
类
ArrayList
是 LinkedList
的一个替代选择,使用动态数组实现,适用于频繁访问元素但插入和删除操作较少的场景。建议阅读 ArrayList 的官方文档。
6.2 Deque
接口
Deque
接口定义了双端队列的操作,LinkedList
实现了这一接口,建议阅读 Deque 的官方文档。
6.3 Queue
接口
Queue
接口定义了队列的操作,LinkedList
也实现了这一接口,建议阅读 Queue 的官方文档。