Java记录 -49- LinkedList源码剖析

从数据集到产品:聊聊Room-to-Room (R2R) 如何影响扫地机器人、AR导航的未来 本文探讨了Room-to-Room (R2R) 数据集如何推动视觉与语言导航(VLN)技术的发展,并重塑扫地机器人和AR导航的未来。通过分析R2R基于Matterport3D的设计及其在真实场景中的应用,揭示了其在提升智能导航精度和自然语言交互能力方面的潜力。文章还讨论了从实验室到产品化的关键技术挑战与解决方案。 阅读详情

public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable

List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。

所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。

LinkedList就是一个链表,其底层使用了双向链表来实现。

LinkedList的两个构造函数实现:

Entry作为节点,构造函数创建了一个空的双向链表。而带参数的构造函数则先调用了不带参数的构造函数,然后将传过来的集合里的元素都添加到链表里。

    private transient Entry<E> header = new Entry<E>(null, null, null);    private transient int size = 0;    /**     * Constructs an empty list.     */    public LinkedList() {        header.next = header.previous = header;    }    /**     * 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);    }

Entry作为链表节点,其实现如下:

Entry作为LinkedList的一个内部类实现。Entry实现了Node功能,element存放数据信息,next指向下一个节点,previous指向前一个节点。其构造函数中实现了数据赋值,和节点指向。

    private static class Entry<E> {        E element;        Entry<E> next;        Entry<E> previous;        Entry(E element, Entry<E> next, Entry<E> previous) {            this.element = element;            this.next = next;            this.previous = previous;        }    }

LinkedList的add方法:

LinkedList的add方法调用了addBefore方法,并将header传入。在addBefore中先创建了一个Entry节点,然后修改指针指向。完全都是双向链表的操作。而在指定位置添加也是调用addBefore方法,只是没有直接传递header节点,而是传递了要添加位置的节点。

    /**     * 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 <tt>true</tt> (as specified by {@link Collection#add})     */    public boolean add(E e) {        addBefore(e, header);        return true;    }     /**     * 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) {        addBefore(element, (index==size ? header : entry(index)));    }    private Entry<E> addBefore(E e, Entry<E> entry) {        Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);        newEntry.previous.next = newEntry;        newEntry.next.previous = newEntry;        size++;        modCount++;        return newEntry;    }

获取数据元素:

LinkedList适合挨个遍历元素,即使指定了位置查询,也需要挨个遍历,因为它只知道链表的头header位置,要通过header去寻找其他节点,比如下面的getFirst和getLast方法是最简单的,直接使用header就可以找到。但指定位置的get方法则需要调用entry定位节点的方法来实现,上面添加元素到指定位置时也需要调用entry方法来找到指定位置的节点。entry方法也是通过header来挨个遍历寻找节点。

    public E get(int index) {        return entry(index).element;    }    public E getLast()  {        if (size==0)            throw new NoSuchElementException();        return header.previous.element;    }    public E getFirst() {        if (size==0)            throw new NoSuchElementException();        return header.next.element;    }    /**     * Returns the indexed entry.     */    private Entry<E> entry(int index) {        if (index < 0 || index >= size)            throw new IndexOutOfBoundsException("Index: "+index+                                                ", Size: "+size);        Entry<E> e = header;        if (index < (size >> 1)) {            for (int i = 0; i <= index; i++)                e = e.next;        } else {            for (int i = size; i > index; i--)                e = e.previous;        }        return e;    }


信号完整性仿真SI之Cadence Sigrity SPEED2000_眼图仿真(四) 今天给大家分享一个仿真的操作流程,是关于Cadence Sigrity SPEED2000的时域波形仿真和眼图仿真。我们会经常看见硬件工程师调试示波器上的一些信号的波形变化,其实这些也可以通过仿真电路的搭建来做出投板前的仿真,来优化走线,以减少版本的迭代次数。如果要和实际的信号保持一致,就要求仿真设置的参数和实际的参数保持一致,这也是仿真的重点和难点。下面先让我们了解一下Cadence Sigrity SPEED2000时域仿真的操作流程: 1.仿真模式选择与文件导入 选择Cadence Sigrity下的 阅读详情

相关推荐

若依Vue整合积木报表实战:Token安全校验全流程解析

本文详细解析了在若依Vue后台系统中安全集成积木报表的全流程,重点阐述了Token安全校验的核心机制。通过前端菜单配置、Token传递、后端权限拦截及自定义Token服务实现,构建了一套完整的企业级报表访问安全防线,确保核心业务数据的安全可控。

t8u9v0的博客 576

<Java八股文面试>ArrayList源码 | Iterator源码 | LinkedList和ArrayList对比

<Java八股文面试>ArrayList源码 | Iterator源码 | LinkedList和ArrayList对比

LXYDSF的博客 1907

UniTouch:多模态触觉对齐技术如何重塑零样本跨模态应用

UniTouch模型通过创新的多模态触觉对齐技术,成功将触觉数据映射到通用的视觉-语言嵌入空间,解决了触觉模态的“孤岛困境”。该技术利用对比学习和传感器特定标记,实现了高质量的零样本学习能力,使模型无需额外训练即可完成触觉分类、描述等任务,并能驱动跨模态生成,为机器人、VR和智能制造等领域提供了强大的触觉理解新范式。

weixin_29044713的博客 409

Java顺序表实现:从静态数组到动态扩容的底层原理与实战

顺序表作为数据结构中最基础的线性存储结构,其核心原理在于利用连续的内存空间实现元素的顺序存储,从而支持高效的随机访问。在Java中,这一原理通过动态数组实现,典型代表是ArrayList,它通过自动扩容机制解决了静态数组容量固定的问题。动态扩容通常采用1.5倍或2倍的因子,在内存利用与性能开销之间取得平衡,其均摊时间复杂度为O(1)。顺序表在随机访问和尾部操作上具有O(1)的时间复杂度优势,但在中间插入删除时需移动元素,为O(n)。这种特性使其非常适合读多写少、尾部操作为主的场景,如数据缓存、批量处理等。本

weixin_34115824的博客 394

【Apollo规划模块探秘】—— 场景(Scenario)驱动的决策引擎

本文深入解析了Apollo自动驾驶平台规划模块的核心机制——场景(Scenario)驱动的决策引擎。文章通过类比日常驾驶,阐述了规划模块如何像经验丰富的司机一样,根据不同的路况(如车道跟随、无保护左转)切换不同的“驾驶模式”。重点剖析了场景管理器(ScenarioManager)如何基于感知信息进行场景判断与切换,以及“场景-阶段-任务”双层状态机如何精密协作,实现灵活、高效且安全的轨迹规划。

rnn9storyteller的博客 278

基于紫光同创FPGA的adf网表文件使用和黑匣子设置

这个时候就可以选择将你的网表文件给到他使用,就是相当于把你的功能模块封装成了一个黑匣子一样,只有外部端口,没有内部代码;,在TOP层的子模块声明里面需要加上/*synthesis syn_black_box */进行黑匣子设置,此时子层 adf 文件作为黑盒是不会综合的,在 device map 时会将顶层综合结果与子层 adf 文件合并传递至布局布线阶段;这些都设置完毕后呢,就可以对工程进行编译和综合了,综合完毕后会生成一个.adf的网表文件,我们要使用的就是这个文件;我这里是把两个子模块的添加了哈;

H2061722的博客 963

深入解析ArrayList扩容机制:从原理到实战避坑指南

在Java集合框架中,动态数组是基础且核心的数据结构,其核心原理在于通过自动扩容机制来支持元素的动态添加。ArrayList作为其典型实现,内部维护一个Object数组,当添加元素导致容量不足时,会触发扩容操作。这一过程涉及新数组空间的申请与旧数据的复制,虽然保证了操作的便利性,但也带来了潜在的性能损耗与内存压力。理解其扩容策略(如默认1.5倍增长)和时间/空间复杂度,对于编写高性能、高稳定性的代码至关重要。在实际工程中,尤其是在处理大规模数据集合时,不合理的使用容易引发内存溢出(OOM)和性能瓶颈。通过预

weixin_34293911的博客 298

CAN 比特率和采样点计算

架构根据输入频率和比特率自动计算。

ldinvicible的专栏 787

03-Redis 快的秘密藏在这里:数据类型与底层数据结构

本文从 Redis 五大数据类型出发,讲清 String、List、Hash、Set、ZSet 背后的底层编码与数据结构,包括 SDS、listpack、quicklist、hashtable、intset、skiplist 等核心实现,并结合编码切换阈值、电商业务场景和常见避坑,帮助读者真正理解 Redis 为什么快、怎么选型、如何避免大 key 和内存浪费。

m0_66500660的博客 498

【单智能体】AI 数据分析智能体案例讲解(附完整源码)

本案例将引导您构建一个基于 AI 的数据分析智能体,让用户能够通过自然语言查询来分析 CSV 和 Excel 文件中的数据,无需掌握 SQL 知识。该智能体使用 Agno Agent 框架集成 OpenAI GPT-4o 模型,并利用 DuckDB 提供高效的数据处理能力。

rengang66的博客 237

Python爬虫应对Cloudflare防护:5秒盾+Turnstile验证码实战(AST反混淆+指纹模拟,成功率95%)

Cloudflare 5秒盾+Turnstile验证码的防护核心,是通过“前端JS挑战+多维度指纹校验”确认请求来源的真实性。用AST反混淆还原CF的验证逻辑,避免执行无用代码导致的验证失败;基于真实浏览器采集指纹,确保指纹维度100%匹配真人环境;结合轻量级JS引擎和自动化工具,模拟完整的浏览器执行环境。该方案的绕过成功率可达95%(剩余5%主要是IP或请求频率导致的风控),适用于绝大多数部署CF防护的网站。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1714

Java记录 -45- List的toString方法

在使用集合时,都习惯性的使用循环遍历其中的每个元素。想知道集合中的每个元素的信息,是不是必须要循环遍历每个元素呢?比如在打印日志信息时,有些集合如List需要记录下来,一般都使用循环遍历集合,将集合中的每个元素的信息再记录下来,有没有更简便的方法呢?对象的信息一般都会使用其toString()方法展示,那么集合的toString()方法又会展示什么信息呢?下面通过一个简单的程序来探索下:publi

秀才的专栏 7342

数据分析案例-2024 年全电动汽车数据集可视化分析

本数据集来源于Kaggle,原始数据集共有177866条数据,17个变量。该数据集显示了目前通过华盛顿州许可部 (DOL) 注册的电池电动汽车 (BEV) 和插电式混合动力电动汽车 (PHEV)。电池电动汽车 (BEV) 是一种全电动汽车,使用一个或多个电池来存储电能,为电机提供动力,并通过将车辆插入电源进行充电。插电式混合动力汽车 (PHEV) 是一种使用一个或多个电池为电动机提供动力的车辆;使用另一种燃料,例如汽油或柴油,为内燃机或其他推进源提供动力;并通过将车辆插入电源来充电。

m0_64336780的博客 1万+

Java记录 -20- 包与导入语句

Java 包与导入语句包(package):用于将完成不同功能的类分门别类,放在不同的目录(包)下。包的命名规则:一般讲公司域名反转作为包名。对于包名,每个字母都需要小写。如果定义类的时候没有使用package,那么java就认为我们所定义的类位于默认包里面(default package)。编译带有package声明的Java源文件有两种方式:1).直接编译,然后根据类中所定义的包名,逐一手工建

秀才的专栏 4079

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Java记录 -80- 深入理解枚举(Enums)

枚举(Enums)JDK1.5加入了一个全新的类型的“类”-- 枚举类型。为此JDK1.5引入了一个新关键字enum。定义枚举类型时本质上就是定义一个类别,只不过很多细节由编译器帮您完成了,所以某种程度上,enum关键字的作用就像是class或interface。当您使用“enum”定义枚举类型时,实质上您定义出来的类型继承自java.lang.Enum类型,而每个枚举的成员其实就是您定义的枚举类

秀才的专栏 3805

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Java记录 -33- 数组存放对象地址

1.数组中存放的是对象的地址。public class ArrayTest3 {    public static void main(String[] args) {        I[] i = new I[2];        i[0] = new C();        i[1] = new C();    }}interface I{}class C implements I{}上面的代

秀才的专栏 3767

Java记录 -40- 定义常量最佳方法

实际工作开发中,我们经常会使用到常量。我们常用的常量,比如:public static final int AGE_OF_PERSON = 18;常量的命名规则:所有单词的字母都是大写,如果有多个单词,那么使用下划线连接即可。在Java中声明final常量时都会加上static关键字,这是为什么?既然是final的不可变的,那就没必要为该类的每个实例对象都声明一个该变量了,该类都使用唯一一个就可以

秀才的专栏 3271

Java记录 -87- java.lang.reflect.Array

java.lang.reflect.Array类提供了动态创建和访问数组元素的各种静态方法。import java.lang.reflect.Array;public class ArrayTester1 {    public static void main(String[] args) throws Exception{                Class classType = Cl

秀才的专栏 2868

Java记录 -63- Java的键值映射Map

public interface Map将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 Map接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口。 Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺序。某些映射实现可明

秀才的专栏 2853

Java记录 -4- 运算符 Operator

当有若干个变量参与运算时,结果类型取决于这些变量中表示范围最大的那个变量类型。比如,参与运算的变量中,有整型int,有双浮点型double,有短整型short,那么最后结果类型就是double。int a = 1;  int b = 2;  double c = (double) a / b;上面代码中,a与b都是整型,但是通过(double)a这种转换将a转换为一个匿名的变量,该变量的类型是do

秀才的专栏 2686

Java记录 -8- 理解面向对象程序设计

Java  理解面向对象程序设计面向对象程序设计(Object Oriented Programing, OOP; Object Oriented Design, OOD).什么是面向对象?在面向对象程序设计中有两个重要的概念:类(class)与对象(object)。类:类是一种抽象的概念,类中包含了数据(通常使用名词来表示)与对数据的操作(通常使用动词来表示)。比如说人就是一个抽象的概念,人具有

秀才的专栏 2682

Java记录 -62- java.util.Collections

在学数组的时候,JDK为我们提供了一个Arrays类,该类提供了许多静态方法来操作数组。同时针对集合类也提供了一个Collections类,同样也提供了许多静态方法来对集合进行操作。Collection 和Collections的区别:java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。

秀才的专栏 2669

Java记录 -28- String Literals字面值

String Literals (Java语言规范Java Language Specifications)The program consisting of the compilation unit : package testPackage;class Test {    public static void main(String[] args) {        String hello 

秀才的专栏 2648

Java记录 -88- 利用反射机制调用对象的私有方法和属性

利用反射机制调用对象的私有方法和属性import java.lang.reflect.Field;import java.lang.reflect.Method;public class TestPrivate {    public static void main(String[] args) throws Exception{        //使用反射机制调用对象的私有方法        

秀才的专栏 2639

Java记录 -57- Object的equals、hashcode和toString方法

Object的hashCode方法是最基础的,equals和toString方法都间接的使用了hashCode方法。一般情况下,我们在重写一个类的equals方法时,都会连带重写hashCode方法。IDE工具eclipse给我们提供了快捷的重写equals和hashCode的方法,而不是其中一个,更说明了这个两个方法一般都会一块进行重写。Object的equals方法:public boolea

秀才的专栏 2636

Java记录 -72- Vector,HashTable和Properties

遗留的集合类:VectorVector实现动态数组。这与ArrayList相似,但两者不同的是:Vector是同步的,并且它包含了许多不属于类集框架的从以前版本遗留下来的方法。随着Java2的公布,Vector被重新设计来扩展AbstractList和实现List接口,因此现在它与类集是完全兼容的。Vector底层也是维护着一个数组。HashTable散列表(HashTable)是原始 java.

秀才的专栏 2628

Java记录 -70- HashSet源码剖析

HashSet不包含重复元素,由哈希表支持。下面我就开始剖析下HashSet的源代码:首先从构造方法开始;    private transient HashMap map;    public HashSet() {        map = new HashMap();    }    public HashSet(Collection c) {        map = new HashMa

秀才的专栏 2628
上一篇: Java记录 -46- ArrayList源码剖析
下一篇: Java记录 -47- 线性数据结构
架构师的清醒
博客等级 码龄14年 291粉丝 397原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值