java集合类学习笔记之LinkList
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的更多相关文章
- java集合类学习笔记之HashMap
1.简述 HashMap是java语言中非常典型的数据结构,也是我们平常用的最多的的集合类之一.它的底层是通过一个单向链表(Node<k,v>)数组(也称之为桶bucket,数组的长度也叫 ...
- java集合类学习笔记之LinkedHashMap
1.简述 LinkedHashMap是HashMap的子类,他们最大的不同是,HashMap内部维护的是一个单向的链表数组,而LinkedHashMap内部维护的是一个双向的链表数组.HashMap是 ...
- java集合类学习笔记之ArrayList
1.简述 ArrayList底层的实现是使用了数组保存所有的数据,所有的操作本质上是对数组的操作,每一个ArrayList实例都有一个默认的容量(数组的大小,默认是10),随着 对ArrayList不 ...
- java集合类学习笔记1
一.集合的接口 java集合类库也将接口与实现相分离.首先看一下大家都熟悉的数据结构-队列是如何分离的.队列接口指出可以在队列的尾部添加元素,在队列的头部删除元素,并且可以查找队列中元素的个数.当需要 ...
- Java集合类学习笔记(Set集合)
Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入. HashSet类的特点: 不能保证元素的排列顺序,顺 ...
- Java集合类学习笔记2
二,具体的集合 集合类型 描述 ArrayList 一种可以动态增长和缩减的索引序列 LinkedList 一种可以在任何位置进行高效地插入和删除操作的有序序列 ArrayDeque 一种用循环数组实 ...
- Java集合类学习笔记(各种Map实现类的性能分析)
HashMap和Hashtable的实现机制几乎一样,但由于Hashtable是一个古老的.线程安全的集合,因此HashMap通常比Hashtable要快. TreeMap比HashMap和Hasht ...
- Java集合类学习笔记(Map集合)
Map用于保存具有映射关系的数据,因此Map集合里保存着两组数据,一组用于保存Map的key,一组用于保存key所对应的value. Map的key不允许重复. HashMap和Hashtable都是 ...
- Java集合类学习笔记(各种线性表性能分析)
ArrayList.LinkedList是线性表的两种典型实现:基于数组的线性表和基于链的线性表. Queue代表了队列,Deque代表了双端队列. 一般来说,由于数组以一块连续内存区来保存所有的数组 ...
随机推荐
- CodeIgniter框架隐藏index.php
问题描述:使用CodeIgniter框架做项目时,在启用REWRITE的伪静态功能的时候,首页可以访问,但是访问其它页面的时候,就提示:“No input file specified.” 原因在于使 ...
- Python 编码机制
python 编码转换 Python的编码机制,unicode, utf-8, utf-16, GBK, GB2312,ISO-8859-1 等编码之间的转换. 常见的编码转换分为以下几种情况: 自动 ...
- WEB前端必备掌握知识
1.跨域: 跨域问题是由于javascript语言安全限制中的同源策略造成的.
- html5调用本机摄像头兼容谷歌浏览器高版本,谷歌浏览器低版本,火狐浏览器
做这个功能的时候在网上查了一些资料,代码如下,在这个代码在谷歌浏览器46版本是没问题的,在火狐浏览器也行,但是在谷歌浏览器高版本下是不兼容的 <div id="body"&g ...
- omitTermFreqAndPositions设置,词频FQ在打分中默认为1
compressed=true|false,是否使用gzip压缩(只有TextField和StrField可以压缩) compressThreshold=压缩阀值 multiValued=true|f ...
- 717. 1-bit and 2-bit Characters最后一位数是否为0
[抄题]: We have two special characters. The first character can be represented by one bit 0. The secon ...
- Web网站的几个QPS
评价一个网站的"大小",处于视角的不同,有很多种衡量的方法,类似文章数,页面数之类的数据非常明显,也没有什么可以争议的.但对于并发来说,争议非常之多,这里就从一个技术的角度开始,谈 ...
- PHP初级经典面试题目汇总
17.isset.empty.is_null的区别 isset 判断变量是否定义或者是否为空 变量存在返回ture,否则返回false 变量定义不赋值返回false unset一个变量,返回false ...
- Maven——依赖
一.依赖的范围 依赖的范围有几个可选值,我们用得到的是:compile.test.provided 三个. [1]从项目结构角度理解 compile 和 test 的区别 [2]从开发和运行这两个不同 ...
- 彻底清除Window7下的360注册表
当流氓360遇到强迫症,将注定有一场厮杀... 今天装了个虚拟机,其中win7系统是在网上随便下载了一个,是非纯净版的,自带了360在内的好多软件,其他软件都轻松删掉,但查看注册表时发现竟然有360残 ...