
Java ArrayList 完整详解一、概述ArrayList是java.util包下基于动态数组实现的 List 集合底层是 Object[] 数组自动扩容支持随机访问、增删改查。线程不安全多线程并发修改会抛ConcurrentModificationException允许存放null元素可重复、有序插入顺序不变查询快、中间/头部删除插入慢需要数组移位类关系ArrayListEextendsAbstractListEimplementsListE,RandomAccess,Cloneable,SerializableRandomAccess标记接口支持下标快速随机访问遍历优先用普通for循环。二、底层原理默认初始容量DEFAULT_CAPACITY 10空构造器先赋值空数组第一次add时才扩容到10节省内存扩容机制新容量 旧容量 旧容量 / 21.5倍扩容若1.5倍仍不够直接取所需最小容量最大容量Integer.MAX_VALUE - 8增删操作数组复制Arrays.copyOf()移位消耗性能三、常用构造方法// 1. 空构造初始数组为空首次add扩容至10ArrayListStringlist1newArrayList();// 2. 指定初始容量推荐已知数据量时使用减少扩容ArrayListIntegerlist2newArrayList(20);// 3. 传入集合复制所有元素ListIntegertempArrays.asList(1,2,3);ArrayListIntegerlist3newArrayList(temp);四、核心常用API1. 添加元素ArrayListStringlistnewArrayList();list.add(A);// 尾部添加list.add(1,B);// 指定下标插入下标不能越界list.addAll(Arrays.asList(C,D));// 批量添加集合2. 获取元素Stringslist.get(0);// 根据下标取值越界抛IndexOutOfBoundsExceptionintsizelist.size();// 获取集合元素个数3. 修改元素list.set(0,AA);// 替换指定下标元素返回旧值4. 删除元素list.remove(0);// 按下标删除返回被删元素list.remove(B);// 按对象删除只删第一个匹配元素返回booleanlist.removeAll(Arrays.asList(C,D));// 删除交集元素list.clear();// 清空所有元素数组保留容量5. 判断与查找list.contains(A);// 是否包含元素list.indexOf(A);// 首个匹配下标无则-1list.lastIndexOf(A);// 最后一个匹配下标list.isEmpty();// 是否为空集合6. 转换数组Object[]arr1list.toArray();String[]arr2list.toArray(newString[0]);// 转指定类型数组五、三种遍历方式1. 普通for推荐随机访问最快for(inti0;ilist.size();i){System.out.println(list.get(i));}2. 增强for循环foreach底层迭代器for(Stringstr:list){System.out.println(str);}3. Iterator迭代器遍历中安全删除IteratorStringitlist.iterator();while(it.hasNext()){Stringsit.next();if(A.equals(s)){it.remove();// 安全删除不会并发修改异常}}❌ 禁止foreach里直接list.remove()会触发并发修改异常。六、线程安全问题ArrayList非线程安全多线程同时读写会报错或数据错乱。解决方案Vector旧集合方法全加synchronized性能差不推荐Collections.synchronizedList()包装成同步集合ListStringsafeListCollections.synchronizedList(newArrayList());CopyOnWriteArrayList读写分离读不加锁写复制新数组读多写少场景首选七、常用示例代码importjava.util.ArrayList;importjava.util.Arrays;publicclassArrayListDemo{publicstaticvoidmain(String[]args){ArrayListIntegernumsnewArrayList();// 添加nums.add(10);nums.add(20);nums.add(30);nums.add(1,15);// 查询System.out.println(nums.get(1));// 15System.out.println(nums.size());// 4// 修改nums.set(0,99);// 删除nums.remove(Integer.valueOf(30));// 遍历for(Integernum:nums){System.out.print(num );}}}八、ArrayList vs LinkedList特性ArrayListLinkedList底层动态数组双向链表查询快 O(1)慢 O(n)头尾增删尾部快头部慢头尾极快 O(1)内存连续数组占用少每个节点存前后指针开销大适用场景大量查询、少量删除频繁头部/中间插入删除九、常见坑下标越界get(i)、add(i,obj)i size 抛异常foreach遍历中调用list.remove()→ ConcurrentModificationException要用迭代器删除Arrays.asList()返回的集合不能add/remove底层固定数组需套new ArrayList()存储基础类型会自动装箱成包装类int→Integer扩容会产生大量数组复制大数据初始化建议指定容量