LinkedList源码解析与性能优化

LinkedList是Java集合框架中基于双向链表实现的列表,它提供了高效的插入和删除操作,但在随机访问方面性能较差。

1. LinkedList简介

LinkedList实现了List接口,基于双向链表实现。每个节点包含了元素本身、指向前一个节点的引用(前驱节点)以及指向后一个节点的引用(后继节点)。这种结构使得在链表中插入和删除元素的效率较高。

2. LinkedList类结构

2.1 类层次结构

java 复制代码
public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
    // ...
}
  • LinkedList继承自AbstractSequentialList,实现了List、Deque接口。
  • 实现了Cloneable接口,表示可以进行克隆。
  • 实现了Serializable接口,表示支持序列化。

2.2 内部节点类

java 复制代码
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. LinkedList构造方法

3.1 无参构造方法

java 复制代码
// 无参构造方法,创建一个空的LinkedList
public LinkedList() {
}

3.2 拷贝构造方法

java 复制代码
// 拷贝构造方法,根据给定集合创建一个LinkedList
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

4. LinkedList插入和删除操作

4.1 添加元素

java 复制代码
// 在链表末尾添加元素
public boolean add(E e) {
    linkLast(e);
    return true;
}

// 在指定位置插入元素
public void add(int index, E element) {
    checkPositionIndex(index);
    // 下标等于对应链表长度,在末尾添加元素
    if (index == size)
        linkLast(element);
    else
        // linkBefore 的逻辑
        // 1.先根据index找到要插入的位置。
        // 2.修改引用,完成插入操作。
        linkBefore(element, node(index));
}

4.2 删除元素

java 复制代码
// 移除指定位置的元素
public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));
}

// 移除指定元素
public boolean remove(Object o) {
    if (o == null) {
        for (Node<E> x = first; x != null; x = x.next) {
            if (x.item == null) {
                unlink(x);
                return true;
            }
        }
    } else {
        for (Node<E> x = first; x != null; x = x.next) {
            if (o.equals(x.item)) {
                unlink(x);
                return true;
            }
        }
    }
    return false;
}

5. LinkedList性能优化建议

5.1 使用Iterator遍历

在遍历LinkedList时,建议使用Iterator而不是通过索引访问元素。因为LinkedList上通过索引访问元素的方式性能较差,而使用Iterator则可以更高效地进行遍历。

java 复制代码
LinkedList<String> linkedList = new LinkedList<>();
// 不推荐
for (int i = 0; i < linkedList.size(); i++) {
    System.out.println(linkedList.get(i));
}
// 推荐
for (String s : linkedList) {
    System.out.println(s);
}

5.2 使用Iterator进行插入和删除

在LinkedList中,使用Iterator进行插入和删除操作是比较高效的。通过Iterator的add和remove方法,可以在遍历时进行元素的插入和删除。

java 复制代码
LinkedList<String> linkedList = new LinkedList<>();
ListIterator<String> iterator = linkedList.listIterator();
while (iterator.hasNext()) {
    String element = iterator.next();
    // 在元素后插入新元素
    iterator.add("New Element");
    // 删除当前元素
    iterator.remove();
}

5.3 使用offer和poll方法

LinkedList实现了Deque接口,提供了offer和poll方法用于在两端进行插入和删除操作,这些方法效率较高。

java 复制代码
LinkedList<String> linkedList = new LinkedList<>();
// 在末尾添加元素
linkedList.offer("Last Element");
// 从头部移除元素
String firstElement = linkedList.poll();

6. 总结

LinkedList是基于双向链表实现的列表,具有高效的插入和删除操作。在实际使用中,建议使用Iterator进行遍历、插入和删除操作,以及利用Deque接口提供的offer和poll方法。通过这些优化策略,能够更好地发挥LinkedList的优势,提升程序性能。

相关推荐
_Evan_Yao4 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd5 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼5 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
thefool1122666 小时前
TCP 1
java·1024程序员节
金銀銅鐵8 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手8 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
paopaokaka_luck10 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节
2301_322414280410 小时前
springboot农产品交易平台的设计与实现08055-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·spring boot·redis·mysql·tomcat·maven·mybatis
考虑考虑11 小时前
JDK26的JEP 500属性
java·后端·java ee
LMT流氓兔11 小时前
第五单元——第十二课:把脚本整理成项目
java·数据库·python·langchain·1024程序员节