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,实现了ListDeque接口。
  • 实现了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进行插入和删除操作是比较高效的。通过Iteratoraddremove方法,可以在遍历时进行元素的插入和删除。

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 使用offerpoll方法

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

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

6. 总结

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

相关推荐
布谷歌8 分钟前
Oops! 更改field的数据类型,影响到rabbitmq消费了...(有关于Java序列化)
java·开发语言·分布式·rabbitmq·java-rabbitmq
PXM的算法星球10 分钟前
java(spring boot)实现向deepseek/GPT等模型的api发送请求/多轮对话(附源码)
java·gpt·microsoft
被程序耽误的胡先生13 分钟前
java中 kafka简单应用
java·开发语言·kafka
F202269748625 分钟前
Spring MVC 对象转换器:初级开发者入门指南
java·spring·mvc
楠枬1 小时前
网页五子棋——对战后端
java·开发语言·spring boot·websocket·spring
YXWik61 小时前
23种设计模式
java·设计模式
不修×蝙蝠1 小时前
Tomcat理论(Ⅰ)
java·服务器·java-ee·tomcat
曲奇是块小饼干_1 小时前
leetcode刷题记录(一百零八)——322. 零钱兑换
java·算法·leetcode·职场和发展
hong_zc1 小时前
SpringBoot 配置文件
java·spring boot·后端