☰
JAVA-ArrayList代码实现与使用总结
2026/10/4 4:56:20 网站建设 项目流程

ArrayList 总结:核心特性、常用接口、代码实现

本文聚焦 Java 集合框架中的ArrayList,从它的定义与核心特性出发,系统梳理所有常用接口的作用与返回值,最后给出整体总结。适合作为学习笔记或面试速查。


目录

  • 一、ArrayList 简介
  • 二、ArrayList 的构造方式
  • 三、ArrayList 常用接口(作用 + 返回值)
  • 四、接口使用示例
  • 五、模拟实现代码
  • 六、总结

一、ArrayList 简介

在集合框架中,ArrayList 是一个普通的类,实现了 List 接口,它的本质是一个动态类型的顺序表。

特性说明
泛型实现以泛型方式实现,使用时必须先实例化,如ArrayList<Integer>
RandomAccess实现了该接口,表明 ArrayList支持随机访问(下标访问 O(1))
Cloneable实现了该接口,表明 ArrayList可以 clone
Serializable实现了该接口,表明 ArrayList支持序列化
非线程安全与 Vector 不同,ArrayList不是线程安全的;单线程下使用,多线程中可选择Vector或CopyOnWriteArrayList
动态扩容底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表

一句话记忆:ArrayList =泛型 + 随机访问 + 可克隆 + 可序列化 + 非线程安全 + 动态扩容的动态顺序表。

底层结构:

  • elementData:真正的Object[]数组,物理地址连续;
  • size:有效元素个数(≠ 数组容量,前者是「装了多少」,后者是「最多能装多少」)。

二、ArrayList 的构造方式

publicstaticvoidmain(String[]args){// 构造一个空的列表List<Integer>list1=newArrayList<>();// 构造一个具有 10 个容量的列表List<Integer>list2=newArrayList<>(10);// 拷贝构造:构造好之后,与源集合中的元素一致ArrayList<Integer>list3=newArrayList<>(list2);// ⚠️ 避免省略类型,否则任意类型都能存放,使用时将是一场灾难Listlist4=newArrayList();list4.add("111");list4.add(100);}
构造方法作用
ArrayList()构造一个空的列表,首次添加元素时才分配容量(10)
ArrayList(int initialCapacity)构造一个具有指定初始容量的列表,可减少扩容次数
ArrayList(Collection<? extends E> c)拷贝构造,元素与源集合一致

建议:始终显式指定泛型,否则编译期类型检查失效,运行时容易出现类型混乱。


三、ArrayList 常用接口(作用 + 返回值)

以下为 ArrayList / List 最常用的接口,逐一给出方法签名、作用、返回值。

方法作用返回值
boolean add(E e)在列表末尾添加元素添加成功返回true
void add(int index, E e)在index位置插入元素,index 及后续元素统一后移一位无返回值
E remove(int index)删除index位置的元素,该元素之后的元素统一前移一位返回被删除的元素
boolean remove(Object o)删除第一次出现的指定元素删除成功返回true,元素不存在返回false
E get(int index)获取index位置的元素(index 必须 ∈ [0, size))返回该位置的元素
E set(int index, E e)将index位置的元素设为e返回被替换的旧元素
boolean contains(Object o)判断列表中是否包含指定元素包含返回true,否则返回false
int indexOf(Object o)查找指定元素第一次出现的位置(从前往后找)找到返回下标,未找到返回 -1
int lastIndexOf(Object o)查找指定元素最后一次出现的位置(从后往前找)找到返回下标,未找到返回 -1
int size()获取列表中有效元素个数返回 size(注意:不是底层数组容量)
void clear()清空列表无返回值
boolean isEmpty()判断列表是否为空为空返回true,否则返回false
List<E> subList(int fromIndex, int toIndex)截取[fromIndex, toIndex)区间,与原列表共用同一个 elementData 数组返回一个 SubList视图(非独立副本)
Object[] toArray()将列表转换为数组返回Object[]数组
Iterator<E> iterator()获取迭代器返回Iterator<E>对象
ListIterator<E> listIterator()获取列表迭代器(支持双向遍历)返回ListIterator<E>对象

⚠️两个极易踩坑的返回值:

  1. remove(int index)返回被删除的元素,而remove(Object o)返回boolean—— 两个重载方法语义完全不同;
  2. subList()返回的是原列表的片段视图(View),与原文 list共享同一个底层数组(同一地址),修改视图会影响原列表。

四、接口使用示例

下面通过一段完整的代码,演示上述常用接口的实际用法。代码中每一步都配有注释,方便对照理解。

publicstaticvoidmain(String[]args){// 1. 构造一个空的列表List<String>list=newArrayList<>();System.out.println("初始列表:"+list+",是否为空:"+list.isEmpty());// 2. 在列表末尾依次添加元素list.add("JavaSE");list.add("JavaWeb");list.add("JavaEE");list.add("JVM");list.add("测试课程");System.out.println("添加元素后:"+list);// 3. 获取 list 中有效元素个数(注意:不是底层数组容量)System.out.println("有效元素个数 size = "+list.size());// 4. 获取和设置 index 位置上的元素,注意 index 必须介于 [0, size) 间System.out.println("get(1) = "+list.get(1));list.set(1,"JavaWEB");// 把下标 1 的元素替换为 "JavaWEB"System.out.println("set 之后 get(1) = "+list.get(1));// 5. 在 list 的 index 位置插入指定元素,index 及后续元素统一往后搬移一个位置list.add(1,"Java数据结构");System.out.println("在下标 1 插入后:"+list);// 6. 删除指定元素(按值删除),找到了就删除,该元素之后的元素统一往前搬移一个位置list.remove("JVM");System.out.println("删除 JVM 后:"+list);// 7. 删除 index 位置上的元素(按下标删除),注意 index 不要超过有效元素个数,否则抛下标越界异常list.remove(list.size()-1);System.out.println("删除最后一个元素后:"+list);// 8. 检测是否包含指定元素,包含返回 true,否则返回 falseif(list.contains("测试课程")){list.add("测试课程");System.out.println("包含测试课程,已再次添加:"+list);}// 9. 查找指定元素第一次出现的位置:indexOf 从前往后找,lastIndexOf 从后往前找list.add("JavaSE");System.out.println("indexOf(JavaSE) = "+list.indexOf("JavaSE"));System.out.println("lastIndexOf(JavaSE) = "+list.lastIndexOf("JavaSE"));// 10. 使 list 中 [0, 4) 之间的元素构成一个新的 SubList 返回,但和 ArrayList 共用同一个 elementData 数组List<String>ret=list.subList(0,4);System.out.println("subList(0,4) = "+ret);// 11. 清空列表list.clear();System.out.println("清空后 size = "+list.size()+",是否为空:"+list.isEmpty());}

运行结果说明:

  • isEmpty()在列表刚创建时返回true,添加元素后返回false;
  • set(1, "JavaWEB")会返回被替换的旧元素(此处为"JavaWeb"),但示例中未打印,读者可自行验证;
  • add(1, "Java数据结构")会把原下标 1 及之后的元素整体后移一位;
  • remove("JVM")按值删除,删除成功后返回true;
  • remove(list.size() - 1)按下标删除最后一个元素,并返回被删除的元素;
  • subList(0, 4)返回的是视图,修改ret会同步影响原list,反之亦然。

💡动手练习:试着在subList返回的ret上调用set(0, "修改"),再打印原list,观察两者是否同步变化,从而加深对「视图共享底层数组」的理解。

五、模拟实现代码

packagemyarraylist;publicclassMyArrayList{//用String来实现privateString[]data=null;privateintsize=0;publicMyArrayList(){data=newString[10];}publicMyArrayList(intcapacity){if(capacity<10){capacity=10;}data=newString[capacity];size=capacity;}privatevoidresize(){String[]newString=newString[data.length+(data.length>>1)];for(inti=0;i<size;i++){newString[i]=data[i];}data=newString;}publicvoidadd(intindex,Stringvalue){if(index<0||index>size){thrownewIndexOutOfBoundsException();}if(size==data.length){resize();}for(inti=size-1;i>=index;i--){data[i+1]=data[i];}data[index]=value;size++;}publicvoidadd(Stringelem){if(size>=data.length){resize();}data[size]=elem;size+=1;}publicStringremove(intindex){if(index<0||index>size){thrownewIndexOutOfBoundsException();}Stringelem=data[index];for(inti=index+1;i<size;i++){data[i-1]=data[i];}size--;returnelem;}publicBooleanremove(Stringelem){for(inti=0;i<size;i++){if(data[i].equals(elem)){remove(i);//因为这里复用的是上一个删除 上一个删除已经减减所以这里不用渐渐就行returntrue;}}returnfalse;}publicStringget(intindex){if(index<0||index>size){thrownewIndexOutOfBoundsException();}returndata[index];}publicvoidset(intindex,Stringelem){if(index<0||index>size){thrownewIndexOutOfBoundsException();}data[index]=elem;}publicvoidclear(){size=0;}publicbooleancontains(Stringelem){for(inti=0;i<size;i++){if(data[i].equals(elem)){returntrue;}}returnfalse;}publicintindexOf(Stringelem){for(inti=0;i<size;i++){if(data[i].equals(elem)){returni;}}return-1;}publicintlastIndexOf(Stringelem){for(inti=size-1;i>=0;i--){if(data[i].equals(elem)){returni;}}return-1;}publicMyArrayListsubList(intfromIndex,inttoIndex){if(fromIndex<0||toIndex>0){thrownewIndexOutOfBoundsException();}MyArrayListlist=newMyArrayList(toIndex-fromIndex);for(inti=fromIndex;i<toIndex;i++){list.add(data[i]);}returnlist;}@OverridepublicStringtoString(){StringBuilderstr=newStringBuilder();str.append("[");for(inti=0;i<size;i++){str.append(data[i]);if(i==size-1){break;}str.append(", ");}str.append("]");returnstr.toString();}publicstaticvoidmain(String[]args){MyArrayListlist=newMyArrayList();list.add("A");list.add("B");list.add("C");list.add(2,"g");list.remove(2);list.remove("A");System.out.println(list);}}

六、总结

  1. ArrayList 本质:Java 集合框架中实现的动态顺序表,底层是一段可动态扩容的连续空间;
  2. 核心特性:泛型实现、支持随机访问、可 clone、可序列化、非线程安全;
  3. 关键接口:add/remove/get/set/contains/indexOf/lastIndexOf/size/clear/subList等,需牢记各自作用与返回值;
  4. 易错点:
    • remove(int index)返回被删除元素,remove(Object o)返回 boolean;
    • subList()返回的是共享底层数组的视图,并非独立副本;
    • size()返回的是有效元素个数,不是底层数组容量;
  5. 使用建议:已知数据量时预先指定初始容量,以减少扩容带来的开销。

如果这篇文章对你有帮助,欢迎点赞 👍 + 收藏 ⭐ + 关注,后续会继续更新 Java 集合框架系列文章!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询