基于JDK1.8.0_191

介绍

  LinkedList是以节点来保存数据的,不像数组在创建的时候需要申请一段连续的空间,LinkedList里的数据是可以存放在不同的空间当中,然后以内存地址作为寻找的工具,比如第一个节点里保存了第二个节点的地址信息,第二个节点又保存了第三个节点的地址信息,以此类推

节点Node的代码如下

  1. private static class Node<E> {
  2. //节点数据
  3. E item;
  4. //下一个节点
  5. Node<E> next;
  6. //上一个节点
  7. Node<E> prev;
  8. Node(Node<E> prev, E element, Node<E> next) {
  9. this.item = element;
  10. this.next = next;
  11. this.prev = prev;
  12. }
  13. }

LinkedList有以下特性

  • 是双向链表,每个节点保存着下一个节点的信息,也保存了上一个节点的信息
  • 不是线程安全的,线程安全可以通过
  1. List list = Collections.synchronizedList(new LinkedList(...));

实现

  • LinkedList可以作为堆栈和队列使用,它包含了许多对应的方法,比如poll、push等等

构造函数

  LinkedList的构造函数比较简单,它不需要初始化大小,因为它不存在扩容的要求

  • public LinkedList();

    第一个是无参构造函数,方法体里什么都不做

  • public LinkedList(Collection<? extends E> c);

    第二个是带初始化数据的,也就是创建一个带有c数据的LinkedList,c数据通过LinkedList的addAll方法插入

部分源码解析

点击查看详细内容

  1. //在末尾插入节点,主要通过linkLast()实现
  2. public boolean add(E e);
  3. /**
  4. * 在末尾插入节点
  5. */
  6. void linkLast(E e) {
  7. //LinkedList专门有last对象,用来保存最后一个节点信息
  8. final Node l = last;
  9. //创建新的节点
  10. final Node newNode = new Node(l, e, null);
  11. last = newNode;
  12. //如果之前LinkedList是null的,那新插入的就是第一个节点
  13. if (l == null)
  14. first = newNode;
  15. else
  16. l.next = newNode;
  17. size++;
  18. modCount++;
  19. }
  20. //在指定位置插入节点
  21. public void add(int index, E element) {
  22.     checkPositionIndex(index);
  23.     //如果指定位置是最后,调用linkLast方法
  24.     if (index == size)
  25.         linkLast(element);
  26.     else
  27.         linkBefore(element, node(index));
  28. }
  29. //在指定节点前面插入节点,下面代码的逻辑就是改变插入位置前一个节点,当前要插入的节点和后一个节点的prev和next的指向
  30. void linkBefore(E e, Node<E> succ) {
  31.     final Node<E> pred = succ.prev;
  32.     final Node<E> newNode = new Node<>(pred, e, succ);
  33.     succ.prev = newNode;
  34.     if (pred == null)
  35.         first = newNode;
  36.     else
  37.         pred.next = newNode;
  38.     size++;
  39.     modCount++;
  40. }
  41.  //在指定位置插入集合
  42. public boolean addAll(int index, Collection<? extends E> c) {
  43.     checkPositionIndex(index);
  44.     //转为数组
  45.     Object[] a = c.toArray();
  46.     int numNew = a.length;
  47.     if (numNew == 0)
  48.         return false;
  49.     //要插入位置的前一个节点和后一个节点
  50.     Node<E> pred, succ;
  51.     if (index == size) {
  52.         succ = null;
  53.         pred = last;
  54.     } else {
  55.         succ = node(index);
  56.         pred = succ.prev;
  57.     }
  58.     //循环插入节点
  59.     for (Object o : a) {
  60.         @SuppressWarnings("unchecked") E e = (E) o;
  61.         Node<E> newNode = new Node<>(pred, e, null);
  62.         if (pred == null)
  63.             first = newNode;
  64.         else
  65.             pred.next = newNode;
  66.         pred = newNode;
  67.     }
  68.     //处理要插入位置的后一个节点
  69.     if (succ == null) {
  70.         last = pred;
  71.     } else {
  72.         pred.next = succ;
  73.         succ.prev = pred;
  74.     }
  75.     size += numNew;
  76.     modCount++;
  77.     return true;
  78. }
  79. //循环遍历LinkedList,然后把所有数据设为NULL
  80. public void clear();
  81. //循环遍历LinkedList,然后做==或者equals操作
  82. public int indexOf(Object o);

LinkedListList的查询

  LinkedList是不建议做频繁的查询操作,那么如果需要查询,哪种更快呢,我们可以试一下

  • 第一种
  1. for(int i = 0; i < list.size; i++){
  2. list.get(i);
  3. }

这种是最差的方式,完全不用测试,因为在for循环里,get操作又是通过另一个for循环实现的,所以这个操作等于是for循环的嵌套

  • 第二种
  1. for(String str : list){}

在1千万数据时,耗时150ms

  • 第三种
  1. for(Iterator<String> iter = list.iterator(); iter.hasNext();iter.next();){}

同样的数据耗时165ms,和第二种差不多

我们通过查看编译后的代码可以知道,第二种编译后的代码是

  1. for(Iterator var4 = list.iterator(); var4.hasNext(); var5 = (String)var4.next()) {}

其实也就是通过迭代的方式

而第三种是

  1. Iterator iter = list.iterator();
  2. while(iter.hasNext()) {iter.next();}

通过while循环操作

本质上第二种和第三种差不多,只要不使用第一种就行

Java源码-集合-LinkedList的更多相关文章

  1. 浅析Java源码之LinkedList

    可以骂人吗???辛辛苦苦写了2个多小时搞到凌晨2点,点击保存草稿退回到了登录页面???登录成功草稿没了???喵喵喵???智障!!气! 很厉害,隔了30分钟,我的登录又失效了,草稿再次回滚,不客气了,* ...

  2. 【数据结构】7.java源码关于LinkedList

    关于LinkedList的源码关注点 1.从底层数据结构,扩容策略2.LinkedList的增删改查3.特殊处理重点关注4.遍历的速度,随机访问和iterator访问效率对比 1.从底层数据结构,扩容 ...

  3. Java源码-集合-ArrayList

    基于JDK1.8.0_191 介绍   在Java中,对于数据的保存和使用有多种方式,主要的目的是以更少的资源消耗解决更多的问题,数组就是其中的一种,它的特点是所有的数据都保存在内存的一段连续空间中, ...

  4. jdk源码->集合->LinkedList

    类的属性 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E&g ...

  5. java源码阅读LinkedList

    1类签名与注释 public class LinkedList<E> extends AbstractSequentialList<E> implements List< ...

  6. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  7. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  8. 【java集合框架源码剖析系列】java源码剖析之TreeSet

    本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...

  9. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

随机推荐

  1. Hadoop架构: 流水线(PipeLine)

    该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 流水线(PipeLine),简单地理解就是客户端向DataNode传输数据(Packet)和接收Dat ...

  2. 「JSOI2015」非诚勿扰

    「JSOI2015」非诚勿扰 传送门 我们首先考虑一名女性选中她列表里第 \(x\) 名男性的概率(假设她列表里共有 \(s\) 名男性): \[ P = p \times (1 - p) ^ {x ...

  3. BZOJ-1563-郁闷的出纳员(权值线段树)

    偏移量要考虑清楚. #include <bits/stdc++.h> using namespace std; const int N=4e5+10; const int BASE=1e5 ...

  4. [转]工作量证明(PoW)权益证明(PoS)和委任权益证明(DPoS)区别

    原文链接 Both in the glossary and in some of our previous posts we've touched on mining and the two main ...

  5. js把树形数据转成扁平数据

    我就直接上代码了都是实际项目里面用到的 1.假设这个json就已经是树型结构数据了(如果不知道怎么实现树型结构数据请看我另一篇博客) var compressedArr=afcommon.treeDa ...

  6. Vue——项目中接口返回值为函数回调,回调函数定义方法(Vue的方法给原生调用)

    在接口调用中,有时会返回给我们一个函数回调,来自动执行我们在前端定义好的某个函数(多出现于通过回调的方式传递某个数值).在原生项目中,我们只要提供一下这个方法就好了,通过函数回调会自动执行.问题就出现 ...

  7. ztree-可拖拽可编辑的树

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - addNodes / editName / rem ...

  8. lucky的时光助理-2017.02

    好久没有更新了, 即便没有听众, 有些故事还是要说给另一个自己听! lucky小姐在这个月开始重新找工作了, 她想找一份自己喜欢的工作, 然后安安稳稳的沉寂下来,她说:她要学些东西,才不会让自己看上去 ...

  9. MySQL8.0.11安装后,使用CMD无法启动mysql服务

    首先,先把mysql的bin路径添加到系统环境变量 这样做可以,直接进入CMD后执行mysql服务,不需要进入mysql的bin文件路径去执行. 第一步:在MySQL的安装文件的bin目录(例如:C: ...

  10. Wireshark 查看指定进程的网络包

    Wireshark 查看指定进程的网络包 打开任务管理器,右键筛选列,选中PID(进程标识符): 找到该进程对应的PID,如1200: 在cmd中执行netstat -ano|findstr 1200 ...