LinkedList源码解析与性能优化

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

1. LinkedList简介

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

2. LinkedList类结构

2.1 类层次结构

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

2.2 内部节点类

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 无参构造方法

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

3.2 拷贝构造方法

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

4. LinkedList插入和删除操作

4.1 添加元素

// 在链表末尾添加元素
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 删除元素

// 移除指定位置的元素
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则可以更高效地进行遍历。

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方法,可以在遍历时进行元素的插入和删除。

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方法用于在两端进行插入和删除操作,这些方法效率较高。

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

6. 总结

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

你可能感兴趣的:(Java,java)