如何通过书名判断自定义Book类实例是否存在于HashSet中
解决HashSet中通过书名查找书籍的问题
你当前代码返回false的核心原因是:HashSet的contains方法会先通过hashCode定位存储桶,再用equals方法判断对象是否相等。你传入的是String类型,而集合里存的是Book对象,默认的equals方法(继承自Object)只会比较对象引用,String和Book属于不同类型,自然不会匹配。
下面提供两种可行的解决方法:
方法一:重写Book类的equals和hashCode方法(推荐)
通过重写这两个方法,让HashSet仅根据书名判断对象是否相等。注意:必须同时重写equals和hashCode,否则会破坏HashSet的内部逻辑一致性。
修改后的Book类代码:
public class Book { private String name; private double price; public Book(String name, double price) { this.name = name; this.price = price; } // 重写equals,仅比较书名 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Book book = (Book) o; return name.equals(book.name); } // 重写hashCode,仅基于书名生成哈希值 @Override public int hashCode() { return name.hashCode(); } // 添加getName方法,用于获取书名 public String getName() { return name; } }
之后在main方法中,创建对应书名的Book对象传入contains:
System.out.println(hs.contains(new Book("Plant Book", 0))); // 此时返回true
这种方法的优势是利用HashSet的O(1)查找效率,适合数据量较大的场景。
方法二:遍历集合逐个比较书名
如果不想修改Book类,可以直接遍历HashSet中的所有Book对象,手动比较书名:
// 普通循环遍历 boolean exists = false; for (Book book : hs) { if ("Plant Book".equals(book.getName())) { exists = true; break; } } System.out.println(exists); // 返回true // 用Stream API简化代码 boolean existsStream = hs.stream().anyMatch(book -> "Plant Book".equals(book.getName())); System.out.println(existsStream); // 返回true
这种方法不需要修改原有类,但查找效率是O(n),数据量大时性能不如方法一。
内容的提问来源于stack exchange,提问作者user19414589
相关产品推荐
相关产品推荐

