热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Java集合源码分析之LikedList

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java集合源码分析之LikedList相关的知识,希望对你有一定的参考价值。一、Lin

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java集合源码分析之LikedList相关的知识,希望对你有一定的参考价值。




一、LinkedList结构

 

  LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列,它是基于双向链表实现的。
  LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
  LinkedList 实现 List 接口,能对它进行队列操作。
  LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
  LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
  LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
  LinkedList 是非同步的。


二、源码说明

  1.LikedList属性


//LinkedList的属性非常简单,一个头结点、一个尾结点、一个表示链表中实际元素个数的变量。
//注意,头结点、尾结点都有transient关键字修饰,这也意味着在序列化时该域是不会序列化的。
//元素个数
transient int size = 0;
//头结点
transient Node first;
//尾节点
transient Node last;

  2.构造函数


public LinkedList() {

}
public LinkedList(Collectionextends E> c) {
this();
addAll(c);
}

  LinkedList没有长度的概念,所以不存在容量不足的问题,因此不需要提供初始化大小的构造方法,因此只提供了两个方法,一个是无参构造方法,初始一个LinkedList对象,一个是将指定的集合元素转化为LinkedList构造方法。

  3.添加方法 add()


public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last
= newNode;
if (l == null)
first
= newNode;
else
l.next
= newNode;
size
++;
modCount
++;
}

  添加方法默认是添加到LinkedList的尾部,首先将last指定的节点赋值给l节点,然后新建节点newNode ,此节点的前驱指向l节点,data = e , next = null , 并将新节点赋值给last节点,它成为了最后一个节点,根据当前List是否为空做出相应的操作。若不为空将l的后继指针修改为newNodw。 size +1 , modCount+1

   4.删除方法


public boolean remove(Object o) {
if (o == null) {
for (Node x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
}
else {
for (Node x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}

  删除方法,先循环遍历列表,找到item == o 的节点,在调用unlink()方法删除

  5.查询 get(index)


//获取指定位置的元素
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//返回指定位置的节点信息,
//LikedList无法随机访问,只能通过遍历的方式找到相应的结点
//为了提高效率,当前位置首先和元素的中间位置开始判断,小于中间位置
//从头结点开始遍历,大于中间位置从尾结点开始遍历
Node node(int index) {
// assert isElementIndex(index);
if (index <(size >> 1)) {
Node
x = first;
for (int i = 0; i )
x = x.next;
return x;
}
else {
Node
x = last;
for (int i = size - 1; i > index; i--)
x
= x.prev;
return x;
}
}


三、内部类介绍

  在LinkedList中除了有一个Node的内部类外,应该还能看到另外两个内部类,那就是ListItr,还有一个是DescendingIterator。

  1.ListItr内部类

  

   



  •     看到方法名之后,就发现不止有向后迭代的方法,还有向前迭代的方法,所以我们就知道了这个ListItr这个内部类干嘛用的了,就是能让linkedList不光能像后迭代,也能向前迭代。

  •     看一下ListItr中的方法,可以发现,在迭代的过程中,还能移除、修改、添加值得操作。

   2.DescendingIterator内部类


 //看一下这个类,还是调用的ListItr,作用是封装一下Itr中几个方法,让使用者以正常的思维去写代码,例如,在从后往前遍历的时候,
   //也是跟从前往后遍历一样,使用next等操作,而不用使用特殊的previous。
private class DescendingIterator implements Iterator {
private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}


四、总结



  1. LinkedList是一个功能很强大的类,可以被当作List集合,双端队列和栈来使用。linkedList本质上是一个双向链表,通过一个Node内部类实现的这种链表结构。

  2. 能存储null值,在查找和删除某元素时,源码中都划分为该元素为null和不为null两种情况来处理,LinkedList中允许元素为null。

  3. 在实现的接口中,应该注意到没有RandomAccess:那么就推荐使用iterator,在其中就有一个foreach,增强的for循环,其中原理也就是iterator,我们在使用的时候,使用foreach或者iterator都可以。

  4. LikedList是顺序存取结构(注意和随机存取结构两个概念搞清楚)

  5. LinkedList在1.8版本有添加了一点新的内容,添加了一个static final 修饰的内部类LLSpliterator 并实现了Spliterator ,

  6. LinkedList底层使用链表来保存集合中的元素,因此随机访问的性能较差,但是插入删除时性能非常的出色。

 

 

参考

   https://www.cnblogs.com/zhangyinhua/p/7688304.html

      https://my.oschina.net/90888/blog/1625505



推荐阅读
author-avatar
我思故我在
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有