修改ArrayList中对象字段后,如何在循环时跳过该对象?
嘿,这个酒店房间预订的需求我之前也碰到过,给你几个实用的实现思路,都是Java里能直接落地的:
首先先明确下我们的基础代码结构(方便你对应自己的业务):
// 抽象基类 abstract class HotelRoom { protected boolean isVacant; public HotelRoom(boolean isVacant) { this.isVacant = isVacant; } public boolean isVacant() { return isVacant; } public void setVacant(boolean vacant) { isVacant = vacant; } // 每个子类必须实现,返回对应的房间类型编号(1-4) public abstract int getRoomType(); } // 四个派生类示例 class SingleRoom extends HotelRoom { public SingleRoom(boolean isVacant) { super(isVacant); } @Override public int getRoomType() { return 1; } } class DoubleRoom extends HotelRoom { public DoubleRoom(boolean isVacant) { super(isVacant); } @Override public int getRoomType() { return 2; } } class SuiteRoom extends HotelRoom { public SuiteRoom(boolean isVacant) { super(isVacant); } @Override public int getRoomType() { return 3; } } class DeluxeSuiteRoom extends HotelRoom { public DeluxeSuiteRoom(boolean isVacant) { super(isVacant); } @Override public int getRoomType() { return 4; } }
方案一:基础循环+状态判断跳过(最直接)
核心思路就是用isVacant字段作为「是否跳过」的开关:每次遍历房间时,先检查这个房间是否已经被预订(isVacant=false),如果是就直接跳过;找到匹配用户选择类型的空置房间后,修改它的状态,之后的循环自然会跳过它。
如果只需要预订一间房间,找到后直接break跳出循环还能提升效率:
import java.util.ArrayList; import java.util.Scanner; public class HotelBookingService { public static void main(String[] args) { // 初始化容量为20的房间集合 ArrayList<HotelRoom> hotelRooms = new ArrayList<>(20); // 模拟添加一些房间(空置/已订都有) for (int i = 0; i < 5; i++) { hotelRooms.add(new SingleRoom(true)); hotelRooms.add(new DoubleRoom(i % 2 == 0)); // 一半空置一半已订 hotelRooms.add(new SuiteRoom(true)); hotelRooms.add(new DeluxeSuiteRoom(true)); } // 获取用户选择的房间类型 Scanner scanner = new Scanner(System.in); System.out.println("请选择要预订的房间类型(1-4):"); int selectedType = scanner.nextInt(); // 处理预订逻辑 boolean bookedSuccess = false; for (HotelRoom room : hotelRooms) { // 核心判断:已预订的房间直接跳过 if (!room.isVacant()) { continue; } // 匹配用户选择的房间类型 if (room.getRoomType() == selectedType) { // 修改字段,标记为已预订 room.setVacant(false); System.out.println("✅ 成功预订" + room.getClass().getSimpleName() + "!"); bookedSuccess = true; // 只订一间的话,直接跳出循环 break; } } if (!bookedSuccess) { System.out.println("❌ 当前没有该类型的空置房间"); } // 后续遍历示例:自动跳过已预订房间 System.out.println("\n当前空置房间列表:"); for (HotelRoom room : hotelRooms) { if (room.isVacant()) { System.out.println("- " + room.getClass().getSimpleName() + "(类型" + room.getRoomType() + ")"); } } } }
方案二:用Stream API简洁实现(推荐)
如果你的需求只是找到第一个符合条件的空置房间并预订,用Java 8+的Stream API会更简洁,而且底层也是找到后就停止处理,效率很高:
// 获取用户选择的selectedType之后,直接用Stream处理 hotelRooms.stream() .filter(room -> room.isVacant() && room.getRoomType() == selectedType) .findFirst() // 定位第一个符合条件的房间 .ifPresentOrElse( room -> { room.setVacant(false); System.out.println("✅ 成功预订" + room.getClass().getSimpleName() + "!"); }, () -> System.out.println("❌ 当前没有该类型的空置房间") );
后续再遍历集合时,只要检查isVacant字段,就能自动跳过已预订的房间,和方案一的效果一致。
方案三:移除已预订房间(可选)
如果你的业务需求是后续循环完全不需要看到已预订的房间(而不是判断状态跳过),可以用Iterator安全地移除已预订的房间,避免ConcurrentModificationException:
import java.util.Iterator; // 处理预订逻辑 boolean bookedSuccess = false; Iterator<HotelRoom> iterator = hotelRooms.iterator(); while (iterator.hasNext()) { HotelRoom room = iterator.next(); // 已预订的房间直接从集合中移除 if (!room.isVacant()) { iterator.remove(); continue; } if (room.getRoomType() == selectedType) { room.setVacant(false); iterator.remove(); // 移除已预订的房间 System.out.println("✅ 成功预订并移除房间!"); bookedSuccess = true; break; } } // 后续遍历集合时,里面只剩空置房间,不需要再判断状态 System.out.println("\n当前空置房间列表:"); for (HotelRoom room : hotelRooms) { System.out.println("- " + room.getClass().getSimpleName() + "(类型" + room.getRoomType() + ")"); }
这个方案适合不需要保留已预订房间信息的场景,比如只需要展示空置房间的界面。
核心总结
不管用哪种方案,核心都是利用isVacant字段的状态来控制是否处理房间:
- 基础循环是最直观的,适合新手理解
- Stream API更简洁优雅,适合现代Java开发
- 移除元素的方案则是根据业务需求的特殊处理
内容的提问来源于stack exchange,提问作者logitech2321
相关产品推荐
相关产品推荐

