1. 容器列表集合
List集合系统应该是日常开发中最常用的API,通常作为面试的最后一道题(JVM、集合、并发)。 集合代码的整体设计也融合了很多编程思想,对于程序员来说要求非常高。 参考和参考价值。
基本要点
API系统
核心功能包括:初始化和加载、元素管理、自动扩展以及两种数据结构:数组和链表。 底层的线程安全操作是基于实现的,与非线程安全操作相比,自然效率会更高。 这是一个通过阅读源码就能发现的功能。
2. 详细说明
1. 阵列特性
是List接口在集合系统中的具体实现类。 底层数组维护数组来加载和管理数据:
当涉及到数组结构时,潜意识查询是根据元素对应的索引进行的,所以速度很快。 如果删除一个元素,可能会移动大量元素,效率相对较低。
数组存储机制:
数组是紧凑且连续的存储。 它们可以被随机访问,并通过下标索引快速找到对应的元素。 因为有提前开辟内存空间的机制,所以相对节省了存储空间。 如果需要扩展数组,则会再次开辟更大的内存。 空间,然后复制那里的所有数据,效率会很低。
2、施工方法
这里我们主要看两种构造方法:
无参数构造函数:初始化,声明一个空数组。
参数化构造函数:如果输入参数大于0,则设置数组的长度。
如果没有通过构造方法指定数组长度,则使用默认的数组长度,并在添加元素的操作过程中设置数组容量。
3. 加载数据
从上面的分析我们可以知道,数组是有容量限制的,但是它总是可以加载元素的。 当然,它也有边界值,但它通常不会加载这么多元素:
超过此限制将引发内存溢出错误。
加载元件:会判断容量是否足够;
当容量不够时,会进行扩容操作。 下面是量化的关键源码:
机制:计算新容量(=15),复制一个新数组,设置容量为。
在指定位置添加:这种方法很少用,也看一下关键的两行代码;
机制:确定数组容量,然后执行非常直接的数组复制操作。 这是一个简单的图表:
如上图所示,假设元素E放置在index=1处,运行如下:
这个过程就像排队一样。 如果在第一个位置插入一位,即后面的都向后移动一位,效率自然就低了。 当然,这也不是绝对的。 如果移动的数组长度足够小,或者一直加在最后,效率就会受到影响。 自然就低很多了。
4. 删除数据
我们来看看上面看到的数据加载的相反逻辑。 我们还是看几行关键源码:
机制:从逻辑上看,类似于添加元素的机制,即将添加位置之后的元素复制到索引开始的位置。 队列中的这个逻辑就像是在前面留一个位置,后面的整个队列就前进一个位置。
效率问题也是一样。 如果删除集合的第一个元素,则所有后续元素都将被移动。 元件去除得越远,对效率的影响就越低。
5、容量及数量
在集合的源码中,有两个关键字段需要明确:
通常容器的大小是通过size获得的,即加载元素的数量。 只有当加载元素触发扩展机制时,容量才会发生变化。
3. 详细说明
1.链表结构的特点
链表结构以非连续、非顺序的物理单元存储,节点元素之间的逻辑顺序是通过链表中的指针链接顺序来实现的。 链表由一系列节点组成,这些节点可以在运行时动态生成。 节点包括两部分:一是存储数据元素的数据字段,二是存储下一个节点地址的指针字段。
功能描述
链表结构解决了数组存储中需要预先知道元素数量的问题,充分利用内存空间,实现灵活的动态内存管理。
2. 结构
底层数据存储结构是基于链表实现的。 首先我们看一下节点的描述:
定义静态类Node来描述节点的结构:元素、前指针和后指针。 在类中定义三个核心变量:
即大小和第一个节点。 这三个变量的说明在源码的注释中已经写得很清楚了:
第一个节点的前一个节点为空,最后一个节点的下一个节点为空,并且该项不为空。
3. 元素管理
一大特点是添加和删除元素的效率高。 根据链表的结构特点看源码。
添加元素
从源码中可以看到,这个方法实际上是在添加元素时调用的,新添加的元素被放置在原链表的最后一个位置:
结合Node类的构造方法,实际操作如下:
核心逻辑是:建立新尾节点和旧尾节点的指针关系,并对首节点变量进行处理。
删除元素
可以根据元素对象或元素索引来删除元素。 最终核心是执行方法:
与添加元素的核心逻辑类似,也是重建节点指针的过程:
通过增删改方法源码分析可以看出,元素的增删改查并不涉及大规模的元素移动,影响的节点也很少,效率自然要高很多。
4、查询方法
基于链表结构存储而不是数组,会对元素查询的效率产生很大影响。 我们先看一下源码:
结合它的结构来看,这个源代码确实非常具有战略意义:
从上面的源码可以看出,查询中中间元素需要遍历的次数越多,效率就越低,所以相对更适合查询第一个元素。
4.源码地址