1、简述

    LinkList的底层其实就是一个双向链表,所谓的链表就是一个LinkList内部静态静态类(Node),对LinkList的所有操作本质上就是通过对LinkList中新建的Node对象

  进行关联引用

2、实现

    a、构造方法:

        LinkList一共提供了两种构造方法:

    

 /**
* Constructs an empty list.
*/
public LinkedList() {
} /**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}

    b、定义内部私有属性

        

transient int size = 0;

    /**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.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;

    LinkList的内部属性只有三个,一个是LinkList的长度,另外两个分别是第一个节点和最后一个节点,每次对LinkList进行更新操作之后,第一个节点和最后一个节点的值都会进行相应的变化。

3、LinkList操作

   增加操作:

      add(E e):

    

/**
* 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;
} /**
* Links e as last element.
*/
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++;
}

    调用add(E e)操作LinkList的时候先new一个Node对象,并设置该节点的上一个元素为之前的最后一个节点,然后再将之前最后一个节点的next属性指向新建的节点

    add(int index, E element):

  

 /**
* Inserts the specified element at the specified position in this list.
* Shifts the element currently at that position (if any) and any
* subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
checkPositionIndex(index); if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}

     调用add(int index, E element)操作的时候和add(E element)方法是一样的,就是通过改变index位置节点的中的next和prev属性的值,再将新创建的节点的next指向原来index位置的节点

 LinkList的删除更新操作本质其实就是通过对内部节点的next和prev属行引用的值进行改变,所以在这里就不再对那些操作一一叙述了

总结:

   之前因为刚看完ArrayList,ArrayList内部是通过数组来对内部数据的保存,所以开始一直纠结这LinkList的数据是保存在哪里的,其实LinkList的数据是直接保存在jvm中的,因为往LinkList中增加数据的时候,其实就是new了一个ArrayList的静态内部类的对象,只不过LinkList的first和last属性指向了这些对象的引用,所以这些对象是一直不会被gc回收的,当LinkList删除一个元素的时候,只不过是将其他的节点对那个节点的引用给删除,然后被删除的那个对象没了引用就会被gc回收。这样的实现方式导致了LinkList里面的元素的jvm中的分布是杂乱的,所以当你根据下标去获取LinkList中的元素是只能通过一个个的去遍历,这样也就导致了它的读取效率低

 

  

java集合类学习笔记之LinkList的更多相关文章

  1. java集合类学习笔记之HashMap

    1.简述 HashMap是java语言中非常典型的数据结构,也是我们平常用的最多的的集合类之一.它的底层是通过一个单向链表(Node<k,v>)数组(也称之为桶bucket,数组的长度也叫 ...

  2. java集合类学习笔记之LinkedHashMap

    1.简述 LinkedHashMap是HashMap的子类,他们最大的不同是,HashMap内部维护的是一个单向的链表数组,而LinkedHashMap内部维护的是一个双向的链表数组.HashMap是 ...

  3. java集合类学习笔记之ArrayList

    1.简述 ArrayList底层的实现是使用了数组保存所有的数据,所有的操作本质上是对数组的操作,每一个ArrayList实例都有一个默认的容量(数组的大小,默认是10),随着 对ArrayList不 ...

  4. java集合类学习笔记1

    一.集合的接口 java集合类库也将接口与实现相分离.首先看一下大家都熟悉的数据结构-队列是如何分离的.队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数.当需要 ...

  5. Java集合类学习笔记(Set集合)

    Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入. HashSet类的特点: 不能保证元素的排列顺序,顺 ...

  6. Java集合类学习笔记2

    二,具体的集合 集合类型 描述 ArrayList 一种可以动态增长和缩减的索引序列 LinkedList 一种可以在任何位置进行高效地插入和删除操作的有序序列 ArrayDeque 一种用循环数组实 ...

  7. Java集合类学习笔记(各种Map实现类的性能分析)

    HashMap和Hashtable的实现机制几乎一样,但由于Hashtable是一个古老的.线程安全的集合,因此HashMap通常比Hashtable要快. TreeMap比HashMap和Hasht ...

  8. Java集合类学习笔记(Map集合)

    Map用于保存具有映射关系的数据,因此Map集合里保存着两组数据,一组用于保存Map的key,一组用于保存key所对应的value. Map的key不允许重复. HashMap和Hashtable都是 ...

  9. Java集合类学习笔记(各种线性表性能分析)

    ArrayList.LinkedList是线性表的两种典型实现:基于数组的线性表和基于链的线性表. Queue代表了队列,Deque代表了双端队列. 一般来说,由于数组以一块连续内存区来保存所有的数组 ...

随机推荐

  1. srvctl和crs_start命令无法启动oracle RAC实例, 但sqlplus可以启动

    今天遇到一个奇怪问题,发现srvctl和crs_start命令无法启动Oracle RAC实例,但用sqlplus却可以正常启动.最终发现原因是在OCR中数据库的状态变成了disable,将此状态更改 ...

  2. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 5 Octave Tutorial—5.5 控制语句: for, while, if 语句

    5.5 控制语句: for, while, if 语句 参考视频: 5 - 5 - Control Statements_ for, while, if statements (13 min).mkv ...

  3. SecureCRT中某些命令提示符下按Backspace显示^H的解决方法

    SecureCRT中某些命令提示符下按Backspace显示^H的解决方法 安装了Apache Derby数据库服务器之后,使用ij客户端去连接derby服务端,可是在ij中输入命令的时候,每当输入错 ...

  4. Spark的几个问题

    1.application是由driver和executor组成的,executor可以分成task,task又可以分成为stage.当一个任务提交给spark之后,spark机群的主节点会出现dri ...

  5. 用eclipse+svn插件,上传新项目到svn服务器

    给定trunk路径,https://svn.ws.125089.com/public/nlp/3434index/IndexByModelSolr/trunk/. 其中自己的web项目名字是Index ...

  6. EF中的批量操作

    阅读目录 插入 更新 删除 在使用EF的过程中,我们经常会遇到需要批量操作数据的场景,批量操作有的时候不仅能提高性能,比如使用SqlBulkCopy进入批量插入的时候,而且比较方便操作,提高效率.那么 ...

  7. NFA/DFA算法

    1.问题概述 随着计算机语言的结构越来越复杂,为了开发优秀的编译器,人们已经渐渐感到将词 法分析独立出来做研究的重要性.不过词法分析器的作用却不限于此.回想一下我们的老师刚刚开始向我们讲述程序设计的时 ...

  8. Docker学习笔记_安装和使用Redis

    一.准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:Docker 二.安装过程 1.搜索Redis                         su ...

  9. Docker学习之路(三)Docker网络详解

    1. Docker的4种网络模式 我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: host模式,使用--net=host ...

  10. Luogu 4900 食堂

    一道把很多东西放在一起的练手题. $$\sum_{i = A}^{B}\sum_{j = 1}^{i}\left \{ \frac{i}{j} \right \} = \sum_{i = A}^{B} ...