JDK9.0 LinkedList源码阅读记录

2024-06-15 01:08

本文主要是介绍JDK9.0 LinkedList源码阅读记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

概述

LinkedList继承体系
java.lang.Objectjava.util.AbstractCollection<E>java.util.AbstractList<E>java.util.AbstractSequentialList<E>java.util.LinkedList<E>
LinkedList定义
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable

说明:
1.LinkedList是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
3.LinkedList 实现 List 接口,能进行队列操作。
4.LinkedList 实现Deque接口,即能将LinkedList当作双端队列使用。
5.LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
6.LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
7.LinkedList 是非同步的。
8.ArrayList底层是由数组支持,而LinkedList是由双向链表实现的,其中的每个对象包含数据的同时还包含指向链表中前一个与后一个元素的引用。

LinkedList方法

public LinkedList();//无参构造器
public LinkedList(Collection<? extends E> c) ;//构造器,以集合c创建LinkedList对象
void linkLast(E e);//给linkFirst的添加last节点添加元素
void linkBefore(E e, Node<E> succ);//在节点succ之前插入元素 
private E unlinkFirst(Node<E> f);//移除节点,用于移除首节点
private E unlinkLast(Node<E> l);//移除节点,用于移除尾节点
E unlink(Node<E> x);//移除x节点
public E getFirst();//获取首节点
public E getLast() ;//获取尾节点
public E removeFirst();//移除首节点
public E removeLast();//移除尾节点 
public void addFirst(E e) ;//添加元素作为首节点
public void addLirst(E e) ;//添加元素作为尾节点
public boolean contains(Object o);//判断是否包含对象o
public int size();//获取当前的包含的元素数量
public boolean add(E e);//添加元素
public boolean remove(Object o);//移除对象
public boolean addAll(Collection<? extends E> c) ;//添加集合c的所有元素
public boolean addAll(int index, Collection<? extends E> c);//在index处 添加集合c的所有元素 
public E get(int index) ;//获取索引为index的元素......等
源代码分析
单向链表和双向链表

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
双向链表添加节点
单向链表(单链表)是链表的一种,它由节点组成,每个节点都包含下一个节点的引用。
双向链表(双链表)是链表的一种。和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个引用指向前后节点,分别指向直接前驱和直接后继。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

LinkedList节点

一个节点包含了元素值,前驱引用和后置引用,可以很方面的找到前后节点.

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;}}
三个属性
transient int size = 0;  //元素的数量
transient Node<E> first; //指向第一个节点
transient Node<E> last;//指向末尾节点
添加节点

可以看出,添加节点时,只是改变节点的next和prev指向即可,因此效率很高

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;elsel.next = newNode;size++;modCount++;
}
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;elsepred.next = newNode;size++;modCount++;
}
删除节点

可以看出,删除节点时,只是改变节点的next和prev指向即可,因此效率很高

 E unlink(Node<E> x) {// assert x != null;final E element = x.item;final Node<E> next = x.next;final Node<E> prev = x.prev;if (prev == null) {first = next;} else {prev.next = next;x.prev = null;}if (next == null) {last = prev;} else {next.prev = prev;x.next = null;}x.item = null;size--;modCount++;return element;
}
查找/删除/设置指定位置的节点元素

LinkedList是链表,不能直接使用索引进行查询,需要进行遍历,其使用的是二分查找,但是只用了一次.如果一直使用二分查找,效率会提高很多.

Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) {Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;} else {Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;}}
迭代器

有两个迭代器Iterator和ListIterator,使用其来对元素进行遍历
两个的实现类都是实现了Iterator接口.
从以下可以看出ListIterator提供的功能更多.
Iterator

public boolean hasNext()
public E next() 
public void remove()

ListIterator

public boolean hasNext();//是否还存在后节点
public E next();//获取当前的元素值
public boolean hasPrevious();//是否存在前节点
public E previous();//获取当前的元素值
public int nextIndex();//获取当前迭代的索引
public int previousIndex();//获取当前迭代的索引
public void remove();//移除元素
public void set(E e) ;//设置当前迭代到元素
public void add(E e);//添加元素至末节点

总结

  1. 与ArrayList相比,ArrayList的数据结构是动态数组,LinkedList的数据结构是双向链表.
  2. LinkedList也可以通过索引进行定位,但是其是通过遍历来进行定位,效率较低,而且只使用了一次二分法.
  3. LinkedList没有进行同步处理,因此会存在线程不安全性,使用时需要注意.
  4. 可以使用迭代器进行访问. 
  5. 实现clone方法,可以被拷贝.
  6. 可以被序列化 .
  7. 相比于 ArrayList,保存同等的数据量的情况下,LinkedList所占用的空间更大,因为每个节点都要保存前后节点的引用.
  8. LinkedList的效率请看这里ArrayList和LinkedList性能比较

相关文章

JDK9.0 ArrayList源码阅读记录
JDK9.0 LinkedList源码阅读记录
ArrayList和LinkedList性能比较
JDK9.0 Vector源码阅读记录
JDK9.0 Hashtable源码阅读记录
Java9.0 HashMap源码阅读记录
JDK9.0 HashSet源码阅读记录

这篇关于JDK9.0 LinkedList源码阅读记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062006

相关文章

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步