Java 1.8-API源码学习之 java.util.ArrayList

1、ArrayList

说到 ArrayList,我们可能会想到这些字眼:底层数据结构是Object类型的数组、查询元素的速度快、增删改速度慢……

下面我们来看一下是哪些因素决定了ArrayList 有这些特点:

1.1、创建对象

在调用 new ArrayList() 空参构造时,实际上是将 this.elementData 指向了一个空数组,也就是说现在数组的长度为 0。

从下面的源码可以分析得出:

  • ArrayList 底层用来存储的数据结构是数组,数组内存储的类型是Object类型。
  • 在调用空参构造时,并没有创建出一个可以存储元素的数组,而是先让数据指针指向一个空数组

1.2、第一次添加元素分析

从整个第一次添加元素分析我们可以得出:

  1. 数组的默认初始化容量是:10。
  2. 数组初始化容量的时机是:第一次添加元素。
  3. 数组扩容的机制是:扩容到原来的 1.5 倍。
  4. ArrayList 底层使用的扩容方法是:Arrays.copyOf。
  5. ArrayList 是线程不安全的。

扩展:

  • 多线程操作 ArrayList 时候,可能会抛出 ConcurrentModificationException ,叫做:并发修改异常(List, Set, Map 接口下非线程安全的类,如果我们使用多线程去操作其实例对象,基本上都会抛出这个异常)。
    解决方法是:使用 Vector、Collections.SynchronizedList 或 CopyOnWriteArrayList ( JDK 1.5 出现,并发编程推荐使用 )
  • 因为 ArrayList 底层存储数据 使用的数据结构是 数组,那么数组的优缺点,ArrayList 也有
    • 优点:查询、排序 效率高
    • 缺点:插入、删除、修改 效率低
  • 抛出 ConcurrentModificationException 的例子:
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= 100; i++) {  //循环创建 100 个线程同时操作 ArrayList
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
发布了103 篇原创文章 · 获赞 29 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_42425970/article/details/104422174