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

相关文章

在Spring Boot中集成RabbitMQ的实战记录

《在SpringBoot中集成RabbitMQ的实战记录》本文介绍SpringBoot集成RabbitMQ的步骤,涵盖配置连接、消息发送与接收,并对比两种定义Exchange与队列的方式:手动声明(... 目录前言准备工作1. 安装 RabbitMQ2. 消息发送者(Producer)配置1. 创建 Spr

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/

统一返回JsonResult踩坑的记录

《统一返回JsonResult踩坑的记录》:本文主要介绍统一返回JsonResult踩坑的记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录统一返回jsonResult踩坑定义了一个统一返回类在使用时,JsonResult没有get/set方法时响应总结统一返回

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

apache的commons-pool2原理与使用实践记录

《apache的commons-pool2原理与使用实践记录》ApacheCommonsPool2是一个高效的对象池化框架,通过复用昂贵资源(如数据库连接、线程、网络连接)优化系统性能,这篇文章主... 目录一、核心原理与组件二、使用步骤详解(以数据库连接池为例)三、高级配置与优化四、典型应用场景五、注意事

SpringBoot实现文件记录日志及日志文件自动归档和压缩

《SpringBoot实现文件记录日志及日志文件自动归档和压缩》Logback是Java日志框架,通过Logger收集日志并经Appender输出至控制台、文件等,SpringBoot配置logbac... 目录1、什么是Logback2、SpringBoot实现文件记录日志,日志文件自动归档和压缩2.1、

qtcreater配置opencv遇到的坑及实践记录

《qtcreater配置opencv遇到的坑及实践记录》我配置opencv不管是按照网上的教程还是deepseek发现都有些问题,下面是我的配置方法以及实践成功的心得,感兴趣的朋友跟随小编一起看看吧... 目录电脑环境下载环境变量配置qmake加入外部库测试配置我配置opencv不管是按照网上的教程还是de