博客
关于我
ArrayList、LinkedList原理
阅读量:652 次
发布时间:2019-03-15

本文共 1817 字,大约阅读时间需要 6 分钟。

ArrayList与线程安全

ArrayList实现机制

ArrayList之所以成为Java开发者常用的集合之一,主要是因为其基于数组实现,具有随机访问和迭代操作的优势。然而,作为一个不安全的集合类,ArrayList在并发环境下可能面临数据一致性问题。

ArrayList的原始实现

ArrayList的底层是一个动态数组,称为elementData。初始化时,默认容量为10。当元素数量增长到容量限制时,会按1.5倍扩展容量,确保操作效率。

ArrayList的构造方式

调用ArrayList的无参构造器时,元素数据数组初始化为空数组。首次添加元素时,会扩容,设定容量为10。若使用有参构造器,则直接创建指定初始容量的数组。

public ArrayList() {    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}

在有参构造器中:

public ArrayList(int initialCapacity) {    if (initialCapacity > 0) {        this.elementData = new Object[initialCapacity];    } else if (initialCapacity == 0) {        this.elementData = EMPTY_ELEMENTDATA;    } else {        throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);    }}

ArrayList的添加与扩容

添加元素时,首先检查当前容量是否足够。如果不够,则调用ensureCapacityInternal方法扩展数组。默认扩容策略是将当前容量增加到原容量的1.5倍。

public boolean add(E e) {    ensureCapacityInternal(size + 1);    elementData[size++] = e;    return true;}

当容量不足时,ensureCapacityInternal方法会构造一个新数组,将原有数据复制到新数组,并设置新的数组地址指向新数组。

remove与set方法的实现

删除或修改元素的操作会导致数组结构被破坏,需要重新计算索引位置。remove方法叫用Arrays.copyOf实现数据复制和数组更新,以保持数据一致性。

ArrayList与LinkedList对比

LinkedList基于双向链表实现,优于ArrayList在以下方面:

  • 插入和删除:在链表结构中,插入和删除操作可以直接通过指针修改,无需大量数组移动。当索引在前半部分时,从头节点开始遍历;否则,从尾节点开始遍历。

List的线程安全实现

为了应对多线程环境下的数据竞态,Java提供了Collections.synchronizedList(List list)方法。通过包装原始列表,提供线程安全的视图。

public static 
List
synchronizedList(List
list) { return (list instanceof RandomAccess ? new SynchronizedRandomAccessList<>(list) : new SynchronizedList<>(list));}

CopyOnWriteArrayList的线程安全机制

CopyOnWriteArrayList通过复制整个列表实现线程安全。每次读取或修改操作前,都会创建一个新的数组副本,确保并发操作下数据的一致性。

迭代器的使用陷阱与优化

在使用增强for循环时,不能修改原始集合。在发现ConcurrentModificationException异常时,需检查是否有其他线程修改了数据,也可以通过避免不必要的读操作来提升性能。

通过以上理解,可以更加合理地选择集合类型,并在并发编程中妥善处理线程安全问题。选择集合不仅关乎性能,还关系到代码的可维护性和稳定性。

转载地址:http://jrymz.baihongyu.com/

你可能感兴趣的文章
OpenCV与AI深度学习 | 基于机器视觉的磁瓦表面缺陷检测方案
查看>>
Opencv中KNN背景分割器
查看>>
OpenCV中基于已知相机方向的透视变形
查看>>
opencv保存图片路径包含中文乱码解决方案
查看>>
opencv图像分割2-GMM
查看>>
OpenCV(1)读写图像
查看>>
OpenCV:概念、历史、应用场景示例、核心模块、安装配置
查看>>
Openlayers中点击地图获取坐标并输出
查看>>
Openlayers图文版实战,vue项目从0到1做基础配置
查看>>
Openlayers实战:modifystart、modifyend互动示例
查看>>
Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
查看>>
Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
查看>>
Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
查看>>
Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
查看>>
openlayers:圆孔相机根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域
查看>>
OpenLDAP(2.4.3x)服务器搭建及配置说明
查看>>
OpenLDAP编译安装及配置
查看>>
OpenMCU(一):STM32F407 FreeRTOS移植
查看>>
OpenMCU(三):STM32F103 FreeRTOS移植
查看>>
OpenMCU(二):GD32E23xx FreeRTOS移植
查看>>