You need to enable JavaScript to run this app. Java如何基于ID校验防止向ArrayList存入重复Book对象
优惠活动
大模型
产品
解决方案
定价
更多

Java如何基于ID校验防止向ArrayList存入重复Book对象

代码判重逻辑失效的原因

你的库存列表inventory泛型为Book类型,调用contains(id)时传入的int类型图书ID会被自动装箱为Integer对象。而ArrayList的contains方法本质是遍历列表存储的所有元素,将传入的对象和每个元素做equals匹配——Integer和Book属于完全不同的类型,永远不可能相等,因此无论库存中是否存在相同ID的图书,inventory.contains(id)都会返回false,判重逻辑自然完全不生效。

可行实现方案

方案1:手动遍历库存列表匹配ID(改动最小,无需额外修改类结构)

这是最直观的实现方式,不需要调整原有类的方法结构,改动成本最低:

  1. 首先确保Book类提供公开的ID获取方法,例如public int getId() { return id; }
  2. 将addBook方法中的原有判断逻辑替换为如下代码:
// 标记是否存在重复ID的图书
boolean isDuplicated = false;
for (Book storedBook : inventory) {
    if (storedBook.getId() == id) {
        isDuplicated = true;
        break;
    }
}

if (isDuplicated) {
    System.out.println("This book is already in the inventory!");
    // 发现重复直接终止当前方法执行,跳过后续录入流程
    return;
}

// 以下为原有新图书录入逻辑
System.out.print("Enter book title: ");
// 读取数字输入后清空缓冲区残留的换行符,避免书名读取异常
scan.nextLine();
String title = scan.nextLine();
System.out.print("Enter book price: ");
double price = scan.nextDouble();
inventory.add(new Book(id, title, price));

注意:原有逻辑中发现重复时执行的id--没有实际作用,既不会改变最终存入的图书ID,也无法阻止后续录入流程,可直接移除;原有Scanner读取书名的逻辑存在换行残留问题,连续调用next()、nextLine()会导致读取到的书名为空,需在读取数字类输入后先调用scan.nextLine()清空输入缓冲区的换行符,再读取字符串内容。

方案2:重写Book类的equals和hashCode方法(适合频繁使用列表方法判重的场景)

如果后续开发中需要频繁使用列表自带的contains方法做判重,可以在Book类中重写equals和hashCode方法,将图书ID作为判断两个Book实例是否相等的唯一依据:

// 写入Book类的重写方法
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Book target = (Book) o;
    return id == target.id;
}

@Override
public int hashCode() {
    return Integer.hashCode(id);
}

修改完成后,判重逻辑可以简化为:根据用户输入的ID构造一个临时Book对象(不需要填充title、price属性,因为相等判断只匹配ID),再调用inventory.contains(临时对象)即可快速判断库存中是否存在相同ID的图书。


内容的提问来源于stack exchange,提问作者CB89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 10:06:03