
本文探讨了如何通过循环迭代和条件匹配,高效地将车辆从一个待停放列表中移除,并停放到合适的车库中,直至待停放列表完全清空。文章详细阐述了基于嵌套循环的解决方案,包括其工作原理、代码实现以及在动态修改列表时需要注意的关键点,旨在提供一种处理复杂列表操作的专业教程。
引言:列表元素条件移除与重排挑战
在软件开发中,我们经常会遇到需要根据特定条件从一个集合(如 ArrayList)中查找并移除元素,同时执行其他相关操作的场景。一个常见的挑战是在迭代过程中动态修改列表,这可能导致索引错乱、元素跳过或 ConcurrentModificationException 等问题。本教程将通过一个车辆停放的实际案例,演示一种健壮且有效的解决方案,以确保所有元素都被正确处理并最终清空列表。
问题场景:车辆停放管理
假设我们有一个 vehicles 列表,其中包含了所有待停放的车辆对象。同时,我们还有一个 garage 列表,代表了所有可用的车库空间。我们的目标是:
遍历 vehicles 列表中的每一辆车。为每辆车在 garage 列表中找到一个合适的车库。匹配条件包括:车库空间与车辆空间匹配、车库类型与车辆类型匹配、以及车库仍有可用容量。一旦车辆成功停放,就将其从 vehicles 列表移除。这个过程需要持续进行,直到 vehicles 列表中的所有车辆都被尝试停放(即列表为空)。
核心策略:循环迭代与条件移除
为了实现上述目标,我们需要一个多层循环结构:
外层 while 循环: 负责持续检查 vehicles 列表是否为空。只要列表中还有车辆,就继续尝试停放。内层 for 循环(遍历车辆): 遍历 vehicles 列表中的每一辆车。最内层 for 循环(遍历车库): 为当前车辆寻找一个合适的车库。条件判断: 在找到车库后,需要根据车辆和车库的属性进行严格匹配。操作与移除: 如果所有条件都满足,则将车辆停放到车库,并从 vehicles 列表中移除该车辆,然后跳出车库循环,处理下一辆车(或重新扫描 vehicles 列表)。
代码实现
以下是实现上述策略的Java代码示例:
import java.util.ArrayList;import java.util.List;// 假设 Vehicle 和 Garage 类已经定义,并包含相应的方法class Vehicle { private int space; private String vehicleType; private String destinationSpace; // 假设有目的地空间属性 public Vehicle(int space, String vehicleType, String destinationSpace) { this.space = space; this.vehicleType = vehicleType; this.destinationSpace = destinationSpace; } public int getSpace() { return space; } public String getvehiclesType() { return vehicleType; } public String getDestinationSpace() { return destinationSpace; } @Override public String toString() { return "Vehicle [type=" + vehicleType + ", space=" + space + "]"; }}class Garage { private int space; private String garageType; // 假设车库有类型限制 private int limit; // 车库容量 private List parkedVehicles; // 停放的车辆 public Garage(int space, String garageType, int limit) { this.space = space; this.garageType = garageType; this.limit = limit; this.parkedVehicles = new ArrayList(); } public int getSpace() { return space; } public boolean garageRequest(String vehicleType) { // 假设车库类型与车辆类型匹配 return this.garageType.equals(vehicleType); } public int getLimit() { return limit - parkedVehicles.size(); // 返回剩余容量 } public void addvehicles(Vehicle v) { if (getLimit() > 0) { parkedVehicles.add(v); System.out.println("Parked " + v + " in Garage [space=" + space + ", type=" + garageType + "]"); } } public List getCarry() { return parkedVehicles; } // 假设有方法来设置当前空间或移除车辆,但在此解决方案中未直接使用 public void setCurrentSpace(String newSpace) { // 示例方法,实际逻辑根据需求实现 System.out.println("Garage " + space + " changed current space to " + newSpace); } public boolean removeVehicles(Vehicle v) { boolean removed = parkedVehicles.remove(v); if (removed) { System.out.println("Removed " + v + " from Garage [space=" + space + ", type=" + garageType + "]"); } return removed; } @Override public String toString() { return "Garage [space=" + space + ", type=" + garageType + ", available=" + getLimit() + "]"; }}public class VehicleParkingManager { private List vehicles; private List garage; public VehicleParkingManager(List vehicles, List garage) { this.vehicles = vehicles; this.garage = garage; } public void parkAllVehicles() { System.out.println("--- Starting Parking Process ---"); System.out.println("Initial Vehicles: " + vehicles.size()); System.out.println("Available Garages: " + garage.size()); while (vehicles.size() > 0) { // 外层循环:只要还有车辆未停放,就继续尝试 boolean parkedInThisIteration = false; // 标记本轮是否有车辆被停放 for (int i = 0; i < vehicles.size(); i++) { // 内层循环:遍历当前待停放车辆列表 Vehicle v = vehicles.get(i); // 获取当前车辆 boolean vehicleParked = false; // 标记当前车辆是否已停放 for (int j = 0; j 0) { g.addvehicles(v); // 将车辆停放到车库 vehicles.remove(i); // 从待停放列表中移除已停放的车辆 i--; // 关键:移除元素后,当前索引i指向了下一个元素,为了不跳过,需要将i减1 parkedInThisIteration = true; vehicleParked = true; break; // 跳出车库循环,因为当前车辆已停放 } } // 如果当前车辆在本轮循环中没有找到车库停放,则继续检查下一辆车 // 如果车辆已被停放,且i被调整,for循环的i++会抵消调整,继续正确迭代 } if (!parkedInThisIteration && vehicles.size() > 0) { System.out.println("No more vehicles could be parked in this iteration. Remaining vehicles: " + vehicles.size()); // 如果一整轮for循环都没有车辆被停放,且列表仍不为空,说明无法再停放,跳出while循环 break; } } System.out.println("--- Parking Process Finished ---"); System.out.println("Remaining Vehicles: " + vehicles.size()); } public static void main(String[] args) { List vehicles = new ArrayList(); vehicles.add(new Vehicle(1, "Car", "A1")); vehicles.add(new Vehicle(2, "Truck", "B2")); vehicles.add(new Vehicle(1, "Car", "A3")); vehicles.add(new Vehicle(3, "Motorcycle", "C1")); vehicles.add(new Vehicle(2, "Car", "B4")); // 无法停放,因为车库2只接受Truck vehicles.add(new Vehicle(1, "Car", "A5")); // 无法停放,因为车库1容量已满 List garages = new ArrayList(); garages.add(new Garage(1, "Car", 1)); // 只能停一辆Car garages.add(new Garage(2, "Truck", 2)); // 只能停两辆Truck garages.add(new Garage(3, "Motorcycle", 1)); // 只能停一辆Motorcycle VehicleParkingManager manager = new VehicleParkingManager(vehicles, garages); manager.parkAllVehicles(); System.out.println("n--- Final State ---"); System.out.println("Vehicles left in list: " + manager.vehicles); for (Garage g : garages) { System.out.println(g + " Parked vehicles: " + g.getCarry()); } }}
注意: 在原始提供的答案中,vehicles.remove(i) 后没有 i–。如果 for 循环是 for (int i = 0; i 0) 循环会确保 for 循环在列表未清空时会重新从 i=0 开始,从而最终处理所有元素。为了更直接且避免潜在的跳过,我在示例代码中加入了 i–,这是在正向遍历并删除时常用的技巧。
代码解析与工作原理
while (vehicles.size() > 0):
这是最外层的控制循环,其作用是确保整个停放过程会一直进行,直到 vehicles 列表为空。这意味着即使在某个内层 for 循环中未能停放所有车辆,只要列表不为空,外层 while 循环就会重新启动内部的车辆扫描过程。parkedInThisIteration 标志用于检测在当前 while 循环的一次完整 for 循环中,是否有任何车辆被成功停放。如果一轮 for 循环结束后,没有车辆被停放,且 vehicles 列表仍不为空,则说明已无法再进行任何停放操作,此时应跳出 while 循环,避免无限循环。
for (int i = 0; i < vehicles.size(); i++):
这是遍历 vehicles 列表中待停放车辆的循环。关键点: 当 vehicles.remove(i) 被调用时,列表会动态缩短,索引 i 之后的元素会向前移动一位。为了确保不会跳过新移动到当前 i 位置的元素,需要在 remove(i) 之后立即执行 i–。这样,在 for 循环的下一次迭代中,i 会被 i++ 抵消,从而再次检查当前(新的) i 位置的元素。
**
以上就是精准匹配与移除:高效清空列表的车辆停放策略的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/59430.html
微信扫一扫
支付宝扫一扫