讲师中心 微信公众号

工具推荐

视频效率加速
updream

一键生成高质量推广成片

立刻MV
立刻MV

低成本歌曲 MV、视频生成

Seko
Seko

AI短剧一键生成成片

Laper
Laper

剧本策划到成片协作

精准匹配与移除:高效清空列表的车辆停放策略

轻磊小哥_6281

轻磊小哥_6281

发布时间:2025-09-25 15:28:01

|

812人浏览过

|

来源于php中文网

原创

精准匹配与移除:高效清空列表的车辆停放策略

本文探讨了如何通过循环迭代和条件匹配,高效地将车辆从一个待停放列表中移除,并停放到合适的车库中,直至待停放列表完全清空。文章详细阐述了基于嵌套循环的解决方案,包括其工作原理、代码实现以及在动态修改列表时需要注意的关键点,旨在提供一种处理复杂列表操作的专业教程。

引言:列表元素条件移除与重排挑战

在软件开发中,我们经常会遇到需要根据特定条件从一个集合(如 ArrayList)中查找并移除元素,同时执行其他相关操作的场景。一个常见的挑战是在迭代过程中动态修改列表,这可能导致索引错乱、元素跳过或 ConcurrentModificationException 等问题。本教程将通过一个车辆停放的实际案例,演示一种健壮且有效的解决方案,以确保所有元素都被正确处理并最终清空列表。

问题场景:车辆停放管理

假设我们有一个 vehicles 列表,其中包含了所有待停放的车辆对象。同时,我们还有一个 garage 列表,代表了所有可用的车库空间。我们的目标是:

  1. 遍历 vehicles 列表中的每一辆车。
  2. 为每辆车在 garage 列表中找到一个合适的车库。
  3. 匹配条件包括:车库空间与车辆空间匹配、车库类型与车辆类型匹配、以及车库仍有可用容量。
  4. 一旦车辆成功停放,就将其从 vehicles 列表移除。
  5. 这个过程需要持续进行,直到 vehicles 列表中的所有车辆都被尝试停放(即列表为空)。

核心策略:循环迭代与条件移除

为了实现上述目标,我们需要一个多层循环结构:

  • 外层 while 循环: 负责持续检查 vehicles 列表是否为空。只要列表中还有车辆,就继续尝试停放。
  • 内层 for 循环(遍历车辆): 遍历 vehicles 列表中的每一辆车。
  • 最内层 for 循环(遍历车库): 为当前车辆寻找一个合适的车库。
  • 条件判断: 在找到车库后,需要根据车辆和车库的属性进行严格匹配。
  • 操作与移除: 如果所有条件都满足,则将车辆停放到车库,并从 vehicles 列表中移除该车辆,然后跳出车库循环,处理下一辆车(或重新扫描 vehicles 列表)。

代码实现

以下是实现上述策略的Java代码示例:

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载
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<Vehicle> 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<Vehicle> 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<Vehicle> vehicles;
    private List<Garage> garage;

    public VehicleParkingManager(List<Vehicle> vehicles, List<Garage> 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 < garage.size(); j++) { // 最内层循环:遍历所有车库
                    Garage g = garage.get(j); // 获取当前车库

                    // 检查停放条件:车库空间匹配、车辆类型匹配、车库有容量
                    if (g.getSpace() == v.getSpace() && g.garageRequest(v.getvehiclesType()) && g.getLimit() > 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<Vehicle> 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<Garage> 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--,这是在正向遍历并删除时常用的技巧。

代码解析与工作原理

  1. while (vehicles.size() > 0):

    • 这是最外层的控制循环,其作用是确保整个停放过程会一直进行,直到 vehicles 列表为空。这意味着即使在某个内层 for 循环中未能停放所有车辆,只要列表不为空,外层 while 循环就会重新启动内部的车辆扫描过程。
    • parkedInThisIteration 标志用于检测在当前 while 循环的一次完整 for 循环中,是否有任何车辆被成功停放。如果一轮 for 循环结束后,没有车辆被停放,且 vehicles 列表仍不为空,则说明已无法再进行任何停放操作,此时应跳出 while 循环,避免无限循环。
  2. for (int i = 0; i

    • 这是遍历 vehicles 列表中待停放车辆的循环。
    • 关键点: 当 vehicles.remove(i) 被调用时,列表会动态缩短,索引 i 之后的元素会向前移动一位。为了确保不会跳过新移动到当前 i 位置的元素,需要在 remove(i) 之后立即执行 i--。这样,在 for 循环的下一次迭代中,i 会被 i++ 抵消,从而再次检查当前(新的) i 位置的元素。
  3. **

热门AI工具

更多
UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7319

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3485

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4568

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

3065

2025.08.29

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

40

2026.11.06

Postman请求头Headers怎么设置
Postman请求头Headers怎么设置

围绕Postman HTTP请求头配置展开,讲解Headers选项的具体使用方式,包括Key和Value参数填写、请求头信息添加、常见Header字段设置及请求头修改方法,帮助用户解决接口调试过程中遇到的请求头配置问题。

20

2026.11.06

Postman接口请求发送教程
Postman接口请求发送教程

详细介绍Postman接口请求的创建与发送方法,涵盖GET和POST请求、URL配置、请求参数、Headers请求头、Body请求体设置以及响应结果查看,帮助用户掌握Postman接口请求的完整操作流程。

20

2026.11.06

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

40

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn