public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList继承自AbstractSequenceList、实现了List及Deque接口。
AbstractSequenceList提供List接口的骨干实现,以减少实现List接口的复杂度。
Deque是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll)。

  • LinkedList的属性
transient int size = 0;             //存储元素的个数
transient Node<E> first;            //头节点                //jdk1.6 Entry<E> header = new Entry<E>(null, null, null);
transient Node<E> last;             //尾节点   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;}}             
  • LinkedList的构造方法
    public LinkedList() {                                   //jdk1.6 header.next = header.previous = header;带有头结点双向循环链表}                                                       //jkd1.7+ 不带头节点的双向链表public LinkedList(Collection<? extends E> c) {this();addAll(c);                                      //conllection 转换成数组 for循环添加}
  • LinkedList的方法
    add方法
   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(element, node(index));       //查找index处的节点,把新节点添加到它的前面}private void checkPositionIndex(int index) {if (!isPositionIndex(index))                //非真就抛异常throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private boolean isPositionIndex(int index) {return index >= 0 && index <= size;         //当于等于0且小于等于当前size的大小}void linkLast(E e) {                                //分2种情况解释   第一次添加                     非第一次添加final Node<E> l = last;                         //第一次添加last为null                          第二次添加last不是null    final Node<E> newNode = new Node<>(l, e, null); //假如第一次添加个String类型的“1”                第二次添加个String类型的“2”last = newNode;                             //newNode的item是“1”,newNode.next=null         newNode的item是“2”,newNode.next=null if (l == null)                                  //nowNode.prev=null,并将成员变量last指向newNode  nowNode.prev="1"first = newNode;                            //因为是第一次添加,l也是null,                   第二次添加,l不是nullelse                                        //将成员变量frist指向newNode                     将当前添加的节点指向上一个节点的next属性l.next = newNode;                           //添加后是[null]["1"][null]                      [null]["1"]["2"][null]size++;                                         //        prve item next                               prve item nextmodCount++;}void linkBefore(E e, Node<E> succ) {// assert succ != null;final Node<E> pred = succ.prev;                         //获取succ前面的一个节点final Node<E> newNode = new Node<>(pred, e, succ);      //新建一个节点,前面指向succ前面一个借点,后面指向succsucc.prev = newNode;                                    //succ前面的节点指向新建的节点if (pred == null)                                       //如果succ前面的节点为空,新建的节点则为头节点first = newNode;elsepred.next = newNode;                                //否则就将前面节点的下一点指向新建的节点size++;modCount++;}

remove方法

    public boolean remove(Object o) {                           //判断要删除的元素是不是nullif (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;}public E remove(int index) {checkElementIndex(index);                               //检查数组下标越界return unlink(node(index));}private void checkElementIndex(int index) {if (!isElementIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}private boolean isElementIndex(int index) {return index >= 0 && index < size;}Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) {                  //假如index小于size的一半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 unlink(Node<E> x) {// assert x != null;                    //假如LinkerList有这么一组数据[1,2,3,4,5] remove index是0的数据final E element = x.item;               //则节点是1 x.item = 1 next  = 2 prev = 3                final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {                     //prev ==null,2现在就是首节点了first = next;                       //这里要注意一点,假如有这么一组数据[1,2,3,null,null,null,8,9],remove index是4} else {                                //item prve next 分别为空 ,只是表示指向的内容是nullprev.next = next;                   //假如删除的不是头结点,将下个节点指向上个节点的下个节点x.prev = null;                      //将删除的节点的上个节点指向设置为null}if (next == null) {                     last = prev;} else {                                 //接着[1,2,3,4,5]来解释next.prev = prev;                    //假如删除的不是尾结点,prve此时是null了,2是首节点,2.prev = null;x.next = null;                       //将删除的节点的下个节点指向设置为null}x.item = null;                           //将删除的节点也置为nullsize--;modCount++;return element;}

set

     public E set(int index, E element) {checkElementIndex(index);               //检查数据下标越界Node<E> x = node(index);                //获取要修改坐标的元素E oldVal = x.item;                      //获取这个坐标元素的item属性x.item = element;                       //将要修改元素的item属性引用指向elementreturn oldVal;}

get

    public E get(int index) {checkElementIndex(index);               //检查数据下标越界return node(index).item;                //for循环来取}

Iterator

    private class ListItr implements ListIterator<E> {              //正序迭代private Node<E> lastReturned = null;private Node<E> next;private int nextIndex;private int expectedModCount = modCount;ListItr(int index) {next = (index == size) ? null : node(index);nextIndex = index;}public boolean hasNext() {return nextIndex < size;}public E next() {checkForComodification();if (!hasNext())throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}public boolean hasPrevious() {return nextIndex > 0;}public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned);if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}public void add(E e) {checkForComodification();lastReturned = null;if (next == null)linkLast(e);elselinkBefore(e, next);nextIndex++;expectedModCount++;}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}private class DescendingIterator implements Iterator<E> {           //倒序迭代private final ListItr itr = new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}

总结

linkedList基于双向链表实现,有序,允许为null,没有固定容量,不需要扩容。
其中的每个对象包含数据的同时还包含指向链表中前一个与后一个元素的引用。

转载于:https://www.cnblogs.com/Ch1nYK/p/8589415.html

LinkedList源码详解相关推荐

  1. 线性表ArrayList和LinkedList源码详解。

    List 描述 线性表抽象接口,所有线性表应该在实现这个接口的基础上进行操作. 接口 package list;/*** Description: 线性表的接口,使用泛型保证类型** @ClassNa ...

  2. 【java】LinkedList1.8源码详解

    目录 前言 概要 属性 构造方法 核心方法 get(int index) set(int index, E element) add(int index, E element) addAll(Coll ...

  3. Java集合框架源码详解系列(一)

     写在前面:大家好!我是晴空๓.如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正,感谢大家的不吝赐教.我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/.非常 ...

  4. 【Live555】live555源码详解(九):ServerMediaSession、ServerMediaSubsession、live555MediaServer

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: ServerMediaSession.ServerMediaSubsession.Dy ...

  5. 【Live555】live555源码详解系列笔记

    [Live555]liveMedia下载.配置.编译.安装.基本概念 [Live555]live555源码详解(一):BasicUsageEnvironment.UsageEnvironment [L ...

  6. 【Live555】live555源码详解(八):testRTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的testRTSPClient实现的三个类所在的位置: ourRTSPClient.StreamClient ...

  7. 【Live555】live555源码详解(七):GenericMediaServer、RTSPServer、RTSPClient

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: GenericMediaServer.RTSPServer.RTSPClient 14 ...

  8. 【Live555】live555源码详解(六):FramedSource、RTPSource、RTPSink

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的三个类所在的位置: FramedSource.RTPSource.RTPSink 11.FramedSou ...

  9. 【Live555】live555源码详解(五):MediaSource、MediaSink、MediaSession、MediaSubsession

    [Live555]live555源码详解系列笔记 继承协作关系图 下面红色表示本博客将要介绍的四个类所在的位置: MediaSource.MediaSink.MediaSession.MediaSub ...

最新文章

  1. Hadoop HDFS copyMergeFromLocal
  2. Spring Boot集成Dubbo多模块项目创建与配置
  3. mysql 批量删除数据
  4. c++ 从混合中英文数字等的string 中按顺序分别输出
  5. git add -A 和 git add . 的区别
  6. liferay 点击build service 出现Cloud not reserve enough space for object heap
  7. linux删除文件夹和文件
  8. c++ 返回string_JVM系列之:String.intern和stringTable
  9. java随机生成1到33数组,JAVA 生成随机数数组
  10. mysql 5.6.17 备份还原_mysql 备份和恢复
  11. python制作图片墙_利用python生成照片墙的示例代码
  12. 【已解决】Protocol ‘https‘ not on whitelist ‘file,crypto,data‘!
  13. Iphone 5s 8.0.2越狱
  14. 吉他屋-吉他谱-吉他教程
  15. 暴雨,她还会再回来的,广东已开通本月降雨套餐
  16. ispring 软件改变PDF阅读困难,电子书轻松阅读!
  17. 格式化字符串漏洞利用 一、引言
  18. 【代码审计】iCMS_v7.0.7 apps.admincp.php页面存在SQL注入漏洞分析
  19. 2017中国各省份GDP排名(预计)
  20. JS判断时间先后顺序

热门文章

  1. es6一维数组转二维数组_技术图文:Numpy 一维数组 VS. Pandas Series
  2. 数据结构链表之循环链表——4
  3. 基于Element-plus封装配置化表单组件(组件的v-model实现)
  4. 三、scrapy爬虫框架——scrapy模拟登陆
  5. python 剪切一行内容到另一个文件
  6. LeetCode 280. 摆动排序
  7. LeetCode 1245. 树的直径(图的最大直径结论)
  8. LeetCode 57. 插入区间(一次遍历)
  9. LeetCode 638. 大礼包(无限背包DP)
  10. LintCode 1353. 根节点到叶节点求和(DFS)