Java源码--LinkedList源码概述

与ArrayList同为List,LinkedList却展现出不同的特性。作为java.util下的另一重要容器,我们下面来探究一下LinkedList的源码实现及特性分析。

上篇文章讲述到,ArrayList用数组来存储数据,伴随数据量的变大,ArrayList动态扩充数组容量。
与之不同,LinkedList使用链表来存储数据,因此它在插入/删除数据方面有着天然的优势,而在读取指定位置的元素时,性能却不及ArrayList速度快。

LinkedList存储元素的变量如下:

transient Node<E> first;

  存储数据的节点:Node类如下:

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; //后节点
	}
}

 可以看出来,所有元素节点连在一起,构成了双向链表(prev指向前一个元素节点,next指向后一个元素节点)。所有数据,保存在Node的item中。相比于单向链表,双向链表提供了两种操作的方向,因此可以提供更快的遍历查找速度,更快的插入、删除元素速度(代价是提升了链表维护的难度,以及一点点存储引用的空间)。

下面看一下LinkedList内部对于双向链表的维护:

在此之前,需要知道的一点:LinkedList额外保存了first和last两个节点,分别指向首位和末尾,作为双向链表的两端入口。

内部维护链表的一系列函数如下(private、protected):

//用e构造Node,将数据插到首位
private void linkFirst(E e)
{
	final Node<E> f = first; //取得首位节点node
	final Node<E> newNode = new Node<>(null, e, f); //构造节点,item为e,prev为null,next指向当前的首位f
	first = newNode; //将first指向newNode,以它作为新的首位
	if (f == null)
		last = newNode; //若之前的首位f不存在,则新的首位节点newNode在作为first的同时,也是last
	else
		f.prev = newNode; //若之前的首位f存在,则将f的prev指向新的首位节点newNode
	size++;
	modCount++;
}

//用e构造Node,将数据插到末尾,原理类似
void linkLast(E e);

//将节点插入到指定节点前
void linkBefore(E e, Node<E> succ)
{
	final Node<E> pred = succ.prev; //取得原先succ之前的节点pred,现在需要将newNode插在succ之前,pred之后
	final Node<E> newNode = new Node<>(pred, e, succ); //构造内容为e的newNode,prev指向pred,next指向succ
	succ.prev = newNode; //将succ的prev指向newNode
	if (pred == null)
		first = newNode; //若pred为空,则将newNode置为first
	else
		pred.next = newNode; //将pred的next指向newNode
	size++;
	modCount++;
}

//将首位first节点从链表去掉
private E unlinkFirst(Node<E> f);

//将末位last节点从链表去掉
private E unlinkLast(Node<E> l);

//将任意位置的节点x从链表去掉
E unlink(Node<E> x)
{
	//分别考虑prev与next为null和非null的情况,修复prev与next的指向
}

  基于上述链表操作函数,LinkedList开放了如下接口(public)

public E getFirst()
{
	//取得first内部的item,返回
}

public E getLast()
{
	//取得last内部的item返回
}

public E removeFirst()
{
	//调用unlinkFirst(Node<E> f), 将first从链表移除
}

public E removeLast()
{
	//调用unlinkLast(Node<E> l), 将last从链表移除
}

public void addFirst(E e)
{
	//将e插入到first之前
}

public void addLast(E e)
{
	//将e插入到last之后
}

public boolean add(E e)
{
	//调用linkLast(e),将e插入到last之后
}

public boolean remove(Object o)
{
	//从first开始遍历链表,找到o,移除节点
}

public int indexOf(Object o)
{
	//从first开始遍历节点,找到o,返回index
}

public int lastIndexOf(Object o)
{
	//从last开始反向遍历链表,找到o,移除链表
}

public boolean contains(Object o)
{
	//从first开始遍历链表,找到o,返回true;或者找不到o,返回false
}

public boolean addAll(Collection<? extends E> c)
{
	//1. 将集合c转成数组
	//2. 遍历数组,对于每个元素,构造node,链在last后面
}

  

总结:LinkedList用双向链表维护元素,相比于ArrayList提供了快速的插入、移除数据操作的同时,也比单向链表的遍历查找速度更快。但是,相比于ArrayList,LinkedList的查找指定index元素效率低(ArrayList使用数组存储数据,可以直接依据索引读取)。

原文地址:https://www.cnblogs.com/xinxinBlog/p/9937651.html

时间: 2024-10-15 00:21:15

Java源码--LinkedList源码概述的相关文章

死磕 java集合之LinkedList源码分析

问题 (1)LinkedList只是一个List吗? (2)LinkedList还有其它什么特性吗? (3)LinkedList为啥经常拿出来跟ArrayList比较? (4)我为什么把LinkedList放在最后一章来讲? 简介 LinkedList是一个以双向链表实现的List,它除了作为List使用,还可以作为队列或者栈来使用,它是怎么实现的呢?让我们一起来学习吧. 继承体系 通过继承体系,我们可以看到LinkedList不仅实现了List接口,还实现了Queue和Deque接口,所以它既

Java集合类库 LinkedList 源码解析

基于JDK 1.7,和ArrayList进行比较分析 Java已经有了ArrayList,用来存放元素,对元素的操作都很方便.为什么还会有LinkedList呢?我们都知道ArrayList获取元素很快,但是插入一个元素很慢,因为ArrayList底层维护的是一个数组,往数组中的某个位置插入一个元素,是很消耗资源的. 而LinkedList插入元素很快,获取任意位置的元素却很慢.这是为什么呢?底层又是怎样实现的呢? 1.继承关系 LinkedList的继承关系图: LinkedList继承的是A

Java 集合之LinkedList源码分析

1.介绍 链表是数据结构中一种很重要的数据结构,一个链表含有一个或者多个节点,每个节点处理保存自己的信息之外还需要保存上一个节点以及下一个节点的指针信息.通过链表的表头就可以访问整个链表的信息.Java API中提供了链表的Java实现---LinkedList下.LinkedList是通过节点的连接实现链表的数据结构,向linkedList中插入或删除元素的速度是特别快,而随机访问的速度相对较慢,这个是由于链表本身的性质造成的,在链表中,每个节点都包含了前一个节点的引用,后一个节点的引用和节点

Java进阶之----LinkedList源码分析

今天在看LinkedList的源代码的时候,遇到了一个坑.我研究源码时,发现LinkedList是一个直线型的链表结构,但是我在baidu搜索资料的时候,关于这部分的源码解析,全部都说LinkedList是一个环形链表结构..我纠结了好长时间,还以为我理解错了,最后还是在Google搜到了结果:因为我看的源码是1.7的而baidu出来的几乎全部都是1.6的.而且也没有对应的说明.在1.7之后,oracle将LinkedList做了一些优化,将1.6中的环形结构优化为了直线型了链表结构.这里要提示

【Java集合】-- LinkedList源码解析

目录 继承体系 数据结构 源码解析 1.属性 2.构造方法 LinkedList() LinkedList(Collection<? extends E> c) 3.添加元素 add(E e) addFirst(E e) addLast(E e) add(int index, E element) offer(E e) offerFirst(E e) offerLast(E e) 总结 4.获取元素 get(int index) getFirst() getLast() peek() 5.删除

JDK源码-LinkedList源码

1,LinkedList: -1,实现了List接口,允许null元素.LinkedList还为链表开头和结尾提供了操作,所以使用LinekedList可以用作堆栈.列队或双端队列. -2,LinkedList实现Deque接口,提供了基于队列的先进先出序列的实现. -3,所有的操作都是按照双重链表来实现的. -4,操作为非线程安全的,如果多个线程中,存在修改链表结构的操作,则必须保证线程安全. 2,LinkedList继承AbstractSequentialList实现Lise.Deque.C

Java - LinkedList源码分析

java提高篇(二二)---LinkedList 一.概述 LinkedList与ArrayList一样实现List接口,只是ArrayList是List接口的大小可变数组的实现,LinkedList是List接口链表的实现.基于链表实现的方式使得LinkedList在插入和删除时更优于ArrayList,而随机访问则比ArrayList逊色些. LinkedList实现所有可选的列表操作,并允许所有的元素包括null. 除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾

Java集合系列之LinkedList源码分析

一.LinkedList简介 LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列,它是基于双向链表实现的. ps:这里有一个问题,就是关于实现LinkedList的数据结构是否为循环的双向链表,上网搜了有很多文章都说是循环的,并且有的文章中但是我看了源代码觉得应该不是循环的? 例如在删除列表尾部节点的代码: private E unlinkLast(Node<E> l) { final E element = l.item; final Node<E> pr

Java集合---LinkedList源码解析

一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clone()与toArray()9.遍历数据:Iterator()二.ListItr 一.源码解析 1. LinkedList类定义. public class LinkedList<E> extends AbstractSequentialList<E> implements List&