《LinkedList源代码阅读》

目录

类结构:

LinkedList的存储结构:

构造方法:

LinkedList的常用方法:

        Deque接口的方法:

迭代器操作:

 线程安全:

优缺点:   

 优点:  

缺点:

总结:


类结构:

LinkedList继承了AbstractSequentialList(AbstractSequentialList 是Java中位于 java.util 包下的一个抽象类,它继承了 AbstractList 类,以最大限度地减少实现由“顺序访问”数据存储(如链表)接口所需的工作。对于随机访问数据(如数组),应优先使用 AbstractList而非此类),实现了List、Deque(队列)、Cloneable(对象拷贝)、Serializable(序列化)接口。

LinkedList的存储结构:

 LinkedList是采用一个个Node节点来组成了一个逻辑上连续,物理地址不连续的双向链表。

first,last分别指向头结点与尾结点。

 prev:指向上一个Node节点。

item:存储的数据。

next:指向下一个Node节点。

注:当Node节点是根节点时,prev为Null,根节点无前驱节点。

        同理当Node节点为尾结点时,next为空,尾结点没有后继节点。

构造方法:

        LinkedList有两个构造方法,一个用于构造一个空的链表,一个用已有的集合创建链表。如下:

 当使用第二个构造方法时,会调用addAll()方法将集合中的元素添加到链表中。

LinkedList的常用方法:

        boolean add(E e) ---添加元素至链表尾部

        

        void addFirst(E e) ---添加元素至链表头部

        

        

                

 private void linkFirst(E e) {
        final Node<E> f = first; //获取链表头结点
        final Node<E> newNode = new Node<>(null, e, f);//创建新节点,新节点的头结点为Null,next指向f,数据为e。
        first = newNode;//将链表头部指向新节点
        if (f == null)//如果链表为空,那么该节点既是头结点也是尾结点
            last = newNode;
        else//如果链表不为空,那么该节点作为原链表头部的前驱节点
            f.prev = newNode;
        size++;//链表的长度+1
        modCount++;
    }

        void addLast(E e) ---添加元素至链表尾部(与addFrist同理)

        E get(int index)---遍历链表,查找指定位置的元素

               

public E get(int index) {
        checkElementIndex(index);//检查index是否正确
        return node(index).item;
    }
 Node<E> node(int index) {
        // assert isElementIndex(index);

        if (index < (size >> 1)) {//如果index<(size/2)
            Node<E> x = first;//获取头结点
            for (int i = 0; i < index; i++)//遍历链表
                x = x.next;
            return x;
        } else {
            Node<E> x = last;//获取尾结点
            for (int i = size - 1; i > index; i--)//反向遍历
                x = x.prev;
            return x;
        }
    }

        E getFrist() ---获取链表头元素(与get()同理)

        E getLast() ---获取链表尾元素(与get()同理)

        int indexOf(Object o)---查找链表指定元素的下标,若不存在,返回-1

        

public int indexOf(Object o) {
        int index = 0;
        if (o == null) {//元素为null
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {//不为空
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

        E remove() ---删除链表头元素

        Boolean remove(Object o)---删除指定内容的元素

        

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

         E remove(int index) ---删除指定位置元素

         E removeFrist() ---删除链表头元素

        E removeLast() ---删除链表尾元素

        default void sort(Compartor c)---按照Comparator比较器,将链表中的所有元素进行排序

        

    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

        T[] toArray(T[] a) ---将链表转换成数组

        

    public Object[] toArray() {
        Object[] result = new Object[size];//创建Object数组
        int i = 0;
        for (Node<E> x = first; x != null; x = x.next)//遍历链表,将元素添加至数组
            result[i++] = x.item;
        return result;//返回数组
    }

        Deque接口的方法:

                addFirst()---将元素添加到链表头部

                

public void addFirst(E e) {
        linkFirst(e);
    }

private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);//新建节点,以头节点为后继节点
        first = newNode;
        //如果链表为空,last节点也指向该节点
        if (f == null)
            last = newNode;
        //否则,将头节点的前驱指针指向新节点
        else
            f.prev = newNode;
        size++;
        modCount++;
    }

        offer(E e)---将数据添加到链表尾部,其内部调用了add(E e)方法。

        

  public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }

E  remove()---获取队首元素并从队列中删除;(会抛出异常)

    public E remove() {
        return removeFirst();
    }

E poll()---获取队首元素并从队列中删除;(返回FALSE或null)

    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }

        E element()---获取队首元素但并不从队列中删除;(抛异常)
        E peek()---获取队首元素但并不从队列中删除;(返回false或null)

迭代器操作:

        LinkedList的iterator()方法内部调用了其listIterator()方法,所以可以只分析listIterator()方法。listIterator()提供了两个重载方法。iterator()方法和listIterator()方法的关系如下:

        

public Iterator<E> iterator() {
        return listIterator();
    }

public ListIterator<E> listIterator() {
        return listIterator(0);
    }

 public ListIterator<E> listIterator(final int index) {
        rangeCheckForAdd(index);
        return new ListItr(index);
    }

         最终都会调用listIterator(int index)方法,其中参数表示迭代器开始的位置。

        

 线程安全:

        非线程安全。

优缺点:   

 优点:  

适用于高效的增删操作

因实现了双端队列,具有更高灵活性

缺点:

因为存储结构影响,获取指定元素的时间复杂度为O(n)
没有随机访问特性

总结:

        LinkedList是基于双端链表的List,其内部的实现源于对链表的操作,适用于频繁增加、删除的情况,不适用于频繁的查找;该类不是线程安全的;另外,由于LinkedList实现了Deque接口,所以LinkedList还有队列的接口,可以使用LinkedList作为队列的实现。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NiKo_.gg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值