ArrayList知识点 & ArrayList 综合案例
ArrayList 核心知识点速记
一、ArrayList 基础定义
ArrayList 是 Java 集合框架中 List 接口 的可调整大小数组实现,位于 java.util 包下,是开发中最常用的动态数组(区别于普通数组的固定长度)。
核心特点
- 底层基于数组实现,支持快速随机访问(通过索引获取元素)。
- 容量可自动扩容(默认初始容量 10,扩容时按 1.5 倍增长)。
- 允许存储重复元素、null 值。
- 非线程安全(多线程环境下需使用
Vector或CopyOnWriteArrayList)。 - 增删操作(尤其是中间位置)效率较低(需移动元素)。
二、核心 API(常用方法)
表格
| 方法 | 功能说明 |
|---|---|
boolean add(E e) |
末尾添加元素,返回是否成功 |
void add(int index, E element) |
指定索引位置插入元素 |
E get(int index) |
获取指定索引的元素 |
E remove(int index) |
删除指定索引的元素,返回被删元素 |
boolean remove(Object o) |
删除第一个匹配的元素,返回是否成功 |
E set(int index, E element) |
修改指定索引的元素,返回原元素 |
int size() |
获取集合中元素的数量 |
boolean isEmpty() |
判断集合是否为空 |
void clear() |
清空集合所有元素 |
int indexOf(Object o) |
获取元素首次出现的索引,不存在返回 - 1 |
boolean contains(Object o) |
判断集合是否包含指定元素 |
三、使用步骤
- 导包:
import java.util.ArrayList; - 创建对象:
- 无参构造(常用):
ArrayList<String> list = new ArrayList<>(); - 指定初始容量:
ArrayList<Integer> list = new ArrayList<>(20);
- 无参构造(常用):
- 调用方法:增删改查核心操作。
基础示例
java
运行
import java.util.ArrayList;
public class ArrayListDemo {
public static void main(String[] args) {
// 1. 创建ArrayList对象(存储字符串类型)
ArrayList<String> foodList = new ArrayList<>();
// 2. 新增元素
foodList.add("麻辣小龙虾");
foodList.add("螺蛳粉");
foodList.add(1, "炸鸡"); // 索引1位置插入
// 3. 查询元素
System.out.println("索引2的元素:" + foodList.get(2)); // 输出:螺蛳粉
System.out.println("集合大小:" + foodList.size()); // 输出:3
// 4. 修改元素
foodList.set(0, "蒜蓉小龙虾");
// 5. 删除元素
foodList.remove(1); // 删除索引1的"炸鸡"
// 6. 遍历元素(增强for循环)
for (String food : foodList) {
System.out.println(food); // 输出:蒜蓉小龙虾、螺蛳粉
}
}
}
四、遍历方式
- 增强 for 循环(推荐,简洁):
java
运行
for (E element : list) { // 处理元素 } - 普通 for 循环(需索引操作时使用):
java
运行
for (int i = 0; i < list.size(); i++) { E element = list.get(i); } - 迭代器(Iterator)(删除元素时推荐,避免并发修改异常):
java
运行
Iterator<E> it = list.iterator(); while (it.hasNext()) { E element = it.next(); if (条件) { it.remove(); // 安全删除 } }
五、常见应用场景
- 存储数量不固定的同类型数据(如外卖菜品列表、用户列表)。
- 需要快速查询(按索引),但增删操作较少的场景。
- 单线程环境下的动态数据存储(多线程需加锁或换线程安全类)。
六、核心对比(与普通数组)
表格
| 特性 | ArrayList | 普通数组 |
|---|---|---|
| 长度 | 动态扩容 | 固定长度 |
| 方法 | 丰富的操作方法(add/remove 等) | 仅能通过索引访问 |
| 存储 | 仅支持引用数据类型(基本类型需用包装类) | 支持基本 / 引用数据类型 |
| 效率 | 随机访问快,增删慢 | 访问快,增删需手动重构 |
总结
ArrayList是动态数组,解决了普通数组长度固定的问题,核心优势是灵活扩容和丰富的操作方法。- 核心操作围绕增(add)、删(remove)、改(set)、查(get) 展开,遍历优先用增强 for 循环。
- 适合查询多、增删少的场景,线程不安全,存储基本类型需使用包装类(如
Integer、String)。
题目一:ArrayList之模仿外卖系统综合案例

一、解题步骤分析
步骤 1:需求拆解与类设计
- 明确需求:实现菜品上架和菜品信息浏览功能,结合面向对象与 ArrayList 集合完成。
- 抽象实体:将 “菜品” 抽象为
Food类,封装菜品的核心数据(名称、原价、优惠价、描述信息)。 - 划分职责:设计
FoodManager类负责业务逻辑(上架、浏览、交互界面),FoodTest类作为程序入口启动系统。
步骤 2:编写菜品类(Food)
- 定义私有成员变量:
name(菜品名)、originalPrice(原价)、discountPrice(优惠价)、info(描述信息)。 - 提供无参 / 带参构造方法,方便创建对象。
- 生成 Getter/Setter 方法,实现对私有变量的安全访问。
- 重写
toString()方法,格式化输出菜品信息,便于浏览查看。
步骤 3:编写菜品管理类(FoodManager)
- 初始化集合:使用
ArrayList<Food>存储所有上架菜品,实现动态数据管理。 - 实现交互界面:
showMenu()方法展示功能菜单,通过循环 + switch 接收用户操作选择。 - 实现上架功能:
addFood()方法读取用户输入,创建Food对象并添加到集合。 - 实现浏览功能:
showAllFoods()方法遍历集合,打印所有菜品信息,空集合时给出提示。
步骤 4:编写测试类(FoodTest)
- 创建
FoodManager对象,调用showMenu()方法启动系统,完成功能测试。
二、完整代码示例
代码一:编写菜品类(Food)
package com.sy.food;
/**
* 菜品类
*/
public class Food {
private String name; // 菜品名称
private double oldPrice; // 原价格
private double vipPrice; // 优惠价格
private String info; // 描述信息
public Food() {
}
public Food(String name, double oldPrice, double vipPrice, String info) {
this.name = name;
this.oldPrice = oldPrice;
this.vipPrice = vipPrice;
this.info = info;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getOldPrice() {
return oldPrice;
}
public void setOldPrice(double oldPrice) {
this.oldPrice = oldPrice;
}
public double getVipPrice() {
return vipPrice;
}
public void setVipPrice(double vipPrice) {
this.vipPrice = vipPrice;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
@Override
public String toString() {
return "Food{" +
"name='" + name + '\'' +
", oldPrice=" + oldPrice +
", vipPrice=" + vipPrice +
", info='" + info + '\'' +
'}';
}
}
代码二:写菜品管理类(FoodManager)
package com.sy.food;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Scanner;
/**
* 菜品管理类(添加菜品 浏览菜品 功能菜单)
*/
public class FoodManage {
// 菜品管理(多种) ==> 集合 集合中储存的是菜品
ArrayList<Food> list = new ArrayList();
// 扫描器(键盘录入)
Scanner sc = new Scanner(System.in);
// 添加菜品方法
public void addFood(){
System.out.println("---------菜品上架---------");
Food food = new Food();
System.out.println("请输入您上架的菜品名称: ");
String name = sc.next();
food.setName(name);
System.out.println("请输入您上架的菜品价格: ");
double oldPrice = sc.nextDouble();
food.setOldPrice(oldPrice);
System.out.println("请输入您上架的菜品优惠价格: ");
double vipPrice = sc.nextDouble();
food.setVipPrice(vipPrice);
System.out.println("请输入您上架的菜品描述信息: ");
String info = sc.next();
food.setInfo(info);
list.add(food);
System.out.println("恭喜您, 上架成功...");
}
// 浏览菜品方法
public void queryFood(){
System.out.println("----当前菜品信息描述如下----");
for (int i = 0; i < list.size(); i++) {
Food food = list.get(i);
System.out.println("菜品名称: " + food.getName());
System.out.println("菜品原价格: " + food.getOldPrice());
System.out.println("菜品优惠价格: " + food.getVipPrice());
System.out.println("菜品描述信息: " + food.getInfo());
System.out.println("----------------------------------------");
}
}
// 操作界面方法
public void start(){
while (true){
// 功能菜单
System.out.println("=======欢迎进入外卖系统=======");
System.out.println("1. 上架菜品(add)");
System.out.println("2. 浏览菜品(query)");
System.out.println("3. 退出系统(exit)");
Scanner sc = new Scanner(System.in);
System.out.println("请输入菜单命令: ");
String command = sc.next();
switch (command){
case "add":
this.addFood();
break;
case "query":
this.queryFood();
break;
case "exit":
return;
default:
System.out.println("您输入的命令有误...");
}
}
}
}
代码三:编写测试类(FoodTest)
package com.sy.food;
import java.util.Scanner;
/**
* 菜品测试类
*/
public class FoodTest {
public static void main(String[] args) {
// 创建操作类
FoodManage foodManage = new FoodManage();
foodManage.start();
}
}
三、知识点总结
1. 面向对象编程核心
- 封装:将菜品属性私有化,通过 Getter/Setter 控制访问,保证数据安全性和完整性。
- 类与对象:
Food是模板,描述菜品的共同特征;每个具体菜品是Food的实例对象。 - 方法设计:按功能拆分方法(上架、浏览、展示菜单),提高代码可读性和复用性。
2. ArrayList 集合应用
- 动态存储:相比数组,
ArrayList可自动扩容,适合存储数量不确定的菜品对象。 - 核心操作:
add(E e):添加菜品对象(上架功能)。isEmpty():判断集合是否为空(浏览前校验)。- 增强 for 循环:遍历集合,批量打印菜品信息。
- 泛型使用:
ArrayList<Food>指定存储类型,避免类型转换异常,提高代码安全性。
3. Java 基础语法
- 输入输出:使用
Scanner接收用户输入,System.out.println展示信息。 - 流程控制:
while(true)实现循环菜单,switch-case处理用户选择。 - 方法重载:重写
toString()方法,自定义对象的字符串表现形式。
题目二:基于 ArrayList 的购物车批量删除枸杞商品案例

一、解题思维分析
步骤 1:需求理解与问题拆解
- 核心需求:从购物车商品列表中,批量删除所有包含 “枸杞” 的商品,并验证删除结果。
- 数据载体:使用
ArrayList<String>存储购物车商品名称,模拟后台数据。 - 关键难点:遍历集合时直接删除元素会引发
ConcurrentModificationException(并发修改异常),需要选择安全的删除方式。
步骤 2:数据初始化
- 创建
ArrayList<String>对象,将商品依次添加到集合中:java
运行
ArrayList<String> cart = new ArrayList<>(); cart.add("Java入门"); cart.add("宁夏枸杞"); cart.add("黑枸杞"); cart.add("人字拖"); cart.add("特级枸杞"); cart.add("枸杞子");
步骤 3:遍历与筛选删除(核心逻辑)
- 筛选规则:判断商品名称是否包含 “枸杞” 关键字(
str.contains("枸杞"))。 - 安全遍历方式选择:
- 迭代器(Iterator)遍历(推荐,避免并发修改异常):
- 通过
iterator()获取迭代器,使用hasNext()判断是否有下一个元素。 - 用
next()获取当前元素,若包含 “枸杞” 则调用iterator.remove()安全删除。
- 倒序 for 循环遍历(备选,避免索引越界):
- 从集合末尾向前遍历(
for (int i = list.size()-1; i >= 0; i--)),若满足条件则调用remove(i)删除。
步骤 4:结果验证
- 打印删除后的集合,确认所有含 “枸杞” 的商品已被移除,仅保留不含 “枸杞” 的商品。
二、完整代码示例
package com.sy.arraylist;
import java.util.ArrayList;
public class ArrayListTest04 {
public static void main(String[] args) {
/**
* 购物车案例: (优化版本二)
* 分析:
* 1.创建一个集合表示购物车 购物车存储商品名称(String)
* 2.将商品添加到购物车中
* 3.遍历出购物车中的每一件商品, 只要商品名称中包含"枸杞"都要删除(批量删除)
*/
// 1.创建一个集合表示购物车 购物车存储商品名称(String)
ArrayList<String> list = new ArrayList<>();
// 2.将商品添加到购物车中
list.add("Java入门");
list.add("宁夏枸杞");
list.add("黑枸杞");
list.add("人字拖");
list.add("特级枸杞");
list.add("枸杞子");
// 打印购物车
System.out.println(list);
// 3.遍历出购物车中的每一件商品, 只要商品名称中包含"枸杞"都要删除(批量删除)
for (int i = list.size() - 1; i > 0; i--) {
/**
* [Java入门, 宁夏枸杞, 黑枸杞, 人字拖, 特级枸杞, 枸杞子]
* 0 1 2 3 4 5
*/
String str = list.get(i);
// System.out.println(str);
// 判断商品中是否包含"枸杞" 删除
if (str.contains("枸杞")){
// 删除元素
list.remove(str);
}
}
// 批量删除后的打印效果
System.out.println(list);
}
}
三、知识点总结
1. ArrayList 遍历与删除核心知识
表格
| 知识点 | 详细说明 |
|---|---|
| 遍历方式 | - 增强 for 循环:简洁直观,但遍历中不能删除元素,否则会抛异常。- 普通 for 循环:可操作索引,但正序删除会导致索引前移,漏删元素。- 迭代器(Iterator):安全删除的标准方式,支持遍历过程中删除元素。 |
| contains () 方法 | String.contains(CharSequence s):判断字符串是否包含指定子串,用于筛选目标商品。 |
| 安全删除技巧 | - 迭代器删除:iterator.remove(),是遍历过程中删除元素的唯一安全方式。- 倒序 for 循环:从后往前遍历删除,避免因索引变化导致漏删。 |
| 并发修改异常 | 原因:使用增强 for 循环或普通 for 循环遍历时,直接调用list.remove()会修改集合结构,触发modCount与expectedModCount不一致,抛出异常。 |
2. 易错点总结
- ❌ 错误:增强 for 循环中直接调用
list.remove(),会触发ConcurrentModificationException。 - ❌ 错误:正序 for 循环删除,会导致后续元素索引前移,造成漏删。
- ✅ 正确:使用迭代器或倒序 for 循环进行删除操作。
更多推荐




所有评论(0)