LinkedList基本原理,与ArrayList的区别

本文介绍了LinkedList的基本原理,它是双向链表,底层基于链表实现,每个元素存储自身及前后节点信息。还对比了LinkedList与ArrayList的区别,包括数据结构上前者是链表、后者是数组,性能上在增删和查询操作各有优劣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、LinkedList基本原理

       LinkedList是一个双向链表,底层基于链表实现,链表内存是散乱的,每一个元素存储本身内存地址的同时还存储上一个元素节点、下一个元素节点信息等。其源码结构如下:

   /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *上一个节点信息
     *            (last.next == null && last.item != null)
     */
    transient Node<E> first;

    /**
     * Pointer to last node.
     * Invariant: (first == null && last == null) ||
     *            (last.next == null && last.item != null)
     */下一个节点信息
    transient Node<E> last;

    /**
     * Constructs an empty list.
     */
    public LinkedList() {
    }

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

从中可知:该链表结构由一个个Node<E>对象连接而成,每一个元素存储本身内存地址的同时还存储上一个元素节点、下一个元素节点信息等

(1)添加元素,源码如下:

    /**
     * Appends the specified element to the end of this list.
     *
     * <p>This method is equivalent to {@link #addLast}.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    /**
     * 作为最后一个元素链接e。
     */
    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  //不是首节点,则将当前元素节点信息给前一个元素节点的next值,这样实现了双向链表结构
            l.next = newNode;
        size++;
        modCount++;
    }

(2)根据index索引删除指定位置的元素信息

/**
     * Removes the element at the specified position in this list.  Shifts any
     * subsequent elements to the left (subtracts one from their indices).
     * Returns the element that was removed from the list.
     *
     * @param index the index of the element to be removed
     * @return the element previously at the specified position
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
    /**
     * Unlinks non-null node x.
     */
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }

从代码可知,根据索引删除步骤如下:

a.根据索引index查询出具体的Node<E>对象

b.引出当前节点对象的上一个节点、下一个节点

c.将前一个节点的next值变为当前节点的下一个节点(prev.next = next)

d.当前节点的下一个节点d的prev值变为当前节点的前一个节点(next.prev = prev)

e.当前节点从链表中脱离出来,内容item设置为null

2、LinkedList与ArrayList的区别

(1)数据结构不同

         LinkedList为双向链表结构,链表内存是散乱的;ArrayList底层为数组方式存储的线性结构,存储结构是有序的

(2)性能方面不同

        a、LinkeList由于使用了链表的结构,因此不需要维护容量的大小。从这点上说,它比ArrayList有一定的性能优势

        b、列表任意位置中增加(删除)元素时,LinkeList只要将指定位置插入(脱离),保存前后元素节点信息,即可实现增加(删除)操作,其效率相对会快;ArrayList是基于数组实现的,而数组是一块连续的内存空间,如果在数组的任意位置插入元素,必然导致在该位置后的所有元素需要重新排列(即重新创建新的数组,重新分配元素位置),因此,其效率相对会比较低。

        c、查询列表集合信息时性能差异:LinkeList(链表内存是散乱的)按序号索引数据需要进行前向或后向遍历查询,效率较低;ArrayList数据结构具有一定的排列顺序(根据索引能直接获取结果arr[i],因为底层为数组,不需要遍历),查询较高

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值