马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
概述
LinkedList 是 Java 集合框架中基于双向链表实现的类,实现了 List 和 Deque 接口。在 Java 17 中,其焦点实现与旧版本保持一致,但在当代 Java 编程中可以结合新特性(如 var、Stream API)更高效地利用。
一、焦点特性(Java 17 视角)
- 双向链表结构:每个节点包含数据、前驱和后继节点的引用,与旧版本一致。
- 高效增删操纵:头尾插入/删除时间复杂度为 O(1),中间插入需遍历链表(O(n))。
- 低效随机访问:按索引访问需遍历链表(O(n)),性能低于 ArrayList。
- 多接口支持:可作为列表、队列(Queue)、双端队列(Deque)或栈(Stack)利用。
- 非线程安全:需手动同步或利用 Collections.synchronizedList() 包装。
- 兼容性:完全支持 Java 17 的模块化体系(JPMS),无缝集成当代 Java 项目。
二、应用场景
- 频仍增删数据:如动态维护任务列表、变乱队列。
- 实现队列/栈:利用 offer()/poll()(队列)或 push()/pop()(栈)方法。
- 操纵头尾元素:比方实现 LRU 缓存、打消操纵(Undo/Redo)。
- 无需预分配内存:链表动态扩展,避免数组复制的开销。
- 结合 Stream API:通过链式操纵处理数据(如过滤、映射)。
三、Java 17 中的代码示例
1. 创建 LinkedList 并操纵元素(利用 var 关键字)
- import java.util.LinkedList;
- public class LinkedListDemo {
- public static void main(String[] args) {
- var list = new LinkedList<String>(); // 类型推断(Java 10+)
- // 添加元素(支持链式调用)
- list.add("A")
- .addFirst("B")
- .addLast("C")
- .add(1, "D");
- System.out.println("初始化后: " + list); // 输出: [B, D, A, C]
- // 删除元素(结合 Lambda 表达式)
- list.removeIf(s -> s.equals("A")); // 删除 "A"
- System.out.println("删除后: " + list); // 输出: [B, D, C]
- }
- }
复制代码 2. 作为双端队列(Deque)利用
- var deque = new LinkedList<Integer>();
- // 头部插入
- deque.offerFirst(10);
- // 尾部插入
- deque.offerLast(20);
- // 头部删除
- System.out.println(deque.pollFirst()); // 输出: 10
- // 尾部删除
- System.out.println(deque.pollLast()); // 输出: 20
复制代码 3. 结合 Stream API 处理数据
- var numbers = new LinkedList<>(List.of(1, 2, 3, 4, 5));
- // 过滤偶数并转换为字符串
- List<String> result = numbers.stream()
- .filter(n -> n % 2 == 0)
- .map(Object::toString)
- .toList();
- System.out.println(result); // 输出: [2, 4]
复制代码 4. 实现 LRU 缓存(最近最少利用)
- public class LRUCache<K, V> {
- private final LinkedList<K> accessOrder = new LinkedList<>();
- private final Map<K, V> cache = new HashMap<>();
- private final int capacity;
- public LRUCache(int capacity) {
- this.capacity = capacity;
- }
- public V get(K key) {
- if (cache.containsKey(key)) {
- accessOrder.remove(key); // 移除旧位置
- accessOrder.addFirst(key); // 更新为最近访问
- return cache.get(key);
- }
- return null;
- }
- public void put(K key, V value) {
- if (cache.size() >= capacity) {
- K oldest = accessOrder.removeLast(); // 删除最久未使用的键
- cache.remove(oldest);
- }
- accessOrder.addFirst(key);
- cache.put(key, value);
- }
- }
复制代码 四、与 ArrayList 的对比(Java 17 优化建议)
场景LinkedList 实用性ArrayList 实用性频仍增删✅ 头尾操纵高效,中间操纵需遍历❌ 中间插入/删除需移动元素随机访问❌ 遍历链表(O(n))✅ 直接索引访问(O(1))内存占用❌ 存储节点指针占用更多内存✅ 连续内存,空间局部性更优Java 17 新特性✅ 结合 Stream API 和 var 简化代码✅ 同样实用 五、Java 17 中的注意事项
1、避免索引遍历:优先利用迭代器或 forEach 方法:
- list.forEach(System.out::println); // 推荐方式
复制代码 2、空值处理:答应存储 null,但需注意空指针异常。
3、线程安全:多线程情况下利用同步包装类:
- var syncList = Collections.synchronizedList(new LinkedList<>());
复制代码 4、内存敏感场景:链表节点占用更多内存,需谨慎用于大规模数据。
5、模式匹配:可结合 Java 17 的 switch 模式匹配处理链表元素:
- Object element = list.getFirst();
- switch (element) {
- case String s -> System.out.println("String: " + s);
- case Integer i -> System.out.println("Integer: " + i);
- default -> System.out.println("Unknown type");
- }
复制代码 六、总结
在 Java 17 中,LinkedList 仍旧是处理频仍增删和双端操纵的理想选择,尤其得当队列、栈、缓存等场景。结合当代 Java 特性(如 var、Stream API)可以提升代码简洁性和可读性。若需快速随机访问或内存敏感,优先选择 ArrayList。根据需求选择数据结构,是高效开发的关键!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |