Java集合类二:LinkedList(源码分析+和ArrayList区别)

上文,我们分析了Collection单列集合接口下List接口的实现类ArrayList,本文就接着来看看他的好兄弟LinkedList

一、宏观关系

在这里插入图片描述
LinkedList和ArrayList一样,都是List接口的实现类。但是和ArrayList不同,LinkedList底层数据结构是双向链表

二、数据结构

//容量
transient int size = 0;
//头节点
transient Node<E> first;
//尾节点
transient Node<E> last;

//内部类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;
        }
}

三、构造方法

//无参构造
public LinkedList() {
}

//有参构造(传入集合)
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
}

public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
}

四、add相关

public boolean add(E e) {
		//尾插法插入
        linkLast(e);
        return true;
}

void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
}

LinkedList提供了双向链表的所有标准操作,包括在列表头部、尾部、指定位置插入和删除元素。默认的插入操作是尾插。

五、remove相关

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;
}

由上述remove方法可见,LinkedList也是可以存储null值的

六、ArrayList与LinkedList的区别

  1. 数据结构:
    ArrayList底层数据结构是数组,而LinkedList底层数据结构是双向链表。
  2. 随机访问:
    ArrayList直接通过索引(因为数组的连续存储特性)时间复杂度O(1);
    LinkedList需要从头或者从尾遍历链表,时间复杂度为O(n)
  3. 插入和删除操作:
    ArrayList尾部插入和删除时间复杂度为O(1),只需要调整数组长度。但是指定位置插入删除需要移动其他元素,时间复杂度为O(n)。
    LinkedList 开始或者结尾位置插入和删除都是O(1),因为只需要调整节点的指针,中间O(n)
  4. 内存占用:
    ArrayList:内存占用相对较小,因为它存储的是数组,数组中的每个元素都是紧密排列的。
    LinkedList:内存占用相对较大,因为每个元素都是一个节点对象,需要额外的内存来存储前后元素的引用。
  5. 使用场景:
    ArrayList:适合于频繁的查找操作,或者在列表的末尾添加和删除元素的场景。
    LinkedList:适合于频繁的插入和删除操作,尤其是在列表的开头或中间,或者需要作为队列

两者都不是线程安全的。如果需要线程安全,可以使用 Vector(类似 ArrayList),或者使用
Collections.synchronizedList 方法包装 ArrayList 或 LinkedList。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值