源码分析之ArrayList

本文详细解读了ArrayList作为Java中常用的数据结构之一,在多线程环境下的线程安全转换方法,以及其内部实现机制。通过分析ArrayList的层次结构、成员属性和部分源码展示,阐述了其在不同场景下的高效使用方法和注意事项,特别是针对数组的动态扩容机制和迭代操作的便捷性。同时,文章强调了ArrayList与LinkedList的区别,以及在实际应用中的优劣势对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码分析之ArrayList

1、概述

ArrayList是java开发中很常用的一种数据结构,其使用简单效率较高,将其视作动态数组来看待比较合适。ArrayList也是非线程安全的,如果在多线程环境下可借助Collections工具类Collections.synchronizedList(list)方法将其转换为线程安全的对象来操作。或者使用并发包下CopyOnWriteArrayList对象,并发包在并发环境下更高效。


2、数据结构

ArrayList的底层实现数据结构就是使用的数组,每次扩容的时候使用本地拷贝方法(System.copy(…))来拷贝数组然后移动数组。所以称ArrayList为动态可变数组。


3、ArrayList部分源码展示

ArrayList层次结构和成员属性

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
        //默认初始化容量大小10
        private static final int DEFAULT_CAPACITY = 10;

        //空对象数组
        private static final Object[] EMPTY_ELEMENTDATA = {};

        //存储元素的对象数组
        private transient Object[] elementData;

        //容器的元素个数
        private int size;
}

备注:其实现了RandomAccess接口,可以随机访问。


插入元素代码

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!(先保证容器大小如需要就扩容)
    elementData[size++] = e;
    return true;
}

检索元素(使用下标)

public E get(int index) {
    rangeCheck(index);//下标校验(是否越界)
    return elementData(index);
}

**备注:**ArrayList大部分操作都是和数组类似,所以操作比较简单


4、注意说明

1、ArrayList的继承和实现体系(实现了List、RandomAccess ...)
2、ArrayList的成员属性(注意transient修饰的属性,不被序列化)
3、ArrayList如果要扩容的话,每次会变成原来容量的1.5倍(使用Arrays的copy方法,其实Arrays底层调用的是本地方法C/C++代码)
4、ArrayList查询和迭代比较便捷(基于index查询和迭代器遍历)
5、ArrayList插入和删除操作通常要使用到System.copy()方法来复制数组数据来移动数据。(所以如果频繁插入和删除的操作并不推荐使用ArrayList对象)
6、迭代ArrayList对象时,如果使用对象修改数据的时候会出现
ConcurrentModificationException(fail- fast快速失败机制),推荐使用迭代器来修改数据(我推测它用的是副本吧,类似ThreadLocal原理)
7、由于java.util下的集合不是并发集合所以当在多线程编程时,推荐使用并发包下的集合对象,或使用Collections.synchronizedCollection(x extends Collection);
8、Arrays、Collections 工具类没理由不会。

备注:ArrayList的应用场景比较广,与LinkedList相对应。其优点是随机读取,缺点是插入元素时需要移动大量元素,效率不太高。


总结:

对于ArrayList的源码研究是比较简单的,重点在于掌握其使用的数据结构数组、其底层借助Arrays、Collections工具类高效实现某些方法


参考

  1. http://www.cnblogs.com/leesf456/p/5308358.html
  2. http://beginnersbook.com/2014/08/arraylist-in-java/
  3. http://blog.youkuaiyun.com/ns_code/article/details/35568011
  4. http://zhangshixi.iteye.com/blog/674856
  5. http://www.ibm.com/developerworks/cn/java/j-lo-set-operation/index.html
  6. http://www.ibm.com/developerworks/cn/java/j-5things2.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值