java - 如何修复允许重复的 HashSet?
问题描述
我正在使用带有java.util.HashSet实现的java.util.Set接口并将其存储在 Map 中。
我将一个对象添加到 Set 然后再次检索 Set 对象,并且能够添加另一个与第一个对象相等的对象。
添加看似相等的对象时,Set.add返回true
,两个相等的对象存储在一个 HashSet 中。这怎么可能?我能做些什么来解决这个明显的 Set 合同破裂?
我正在通过 IntelliJ IDEA 2018.3.6 使用 Java 12,并检查了我的java.lang.Object.hashCode实现,以了解我添加到 Set 中的两个对象的类,两者都返回相同的哈希码。我还检查了java.lang.Objects.equals实现,并true
在使用该方法检查它们的相等性时返回。两个对象都包装在另一个对象 Entity 中,但它只转发对象hashCode
和equals
实现。
class Model {
...
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Offer)) {
return false;
}
Offer offer = (Offer) obj;
return Objects.equals(id, offer.id)
&& Objects.equals(name, offer.name)
;
}
@Override
public int hashCode() {
int result = 1;
result = 31 * result + Objects.hashCode(id);
result = 31 * result + Objects.hashCode(name);
return result;
}
...
}
class Store {
...
private static class Entry {
Object value;
Entry(Object value) {
this.value = value;
}
Object getValue() {
return value;
}
@Override
public boolean equals(Object obj) {
return Objects.equals(value, obj);
}
@Override
public int hashCode() {
return value.hashCode();
}
@Override
public String toString() {
return "Entry[value = " + value + "]";
}
}
...
private Map<Class<?>, Set<Entry>> data;
...
private Set<Entry> get(Class<?> type) {
return data.getOrDefault(type, new HashSet<>());
}
@Override
public void persist(Object obj) {
Entry entry = new Entry(obj);
Set<Entry> objects = get(obj.getClass());
if (objects == null) {
objects = new HashSet<>();
}
if (!objects.add(entry)) {
throw new ObjectExistsException
("Object already exists: " + obj);
}
data.put(obj.getClass(), objects);
}
...
}
当obj1
和obj2
类型 Model 相等并且objects
已经包含obj1
在一个 Entry 对象中时,我希望obj2
不要添加到objects
whenobj2
被包装entry
并objects.add(entry)
返回false
然后抛出 ObjectExistsException 的时候。
然而,实际发生的是返回objects.add(entry)
并被true
添加到.obj2
entity
objects
解决方案
@Override
public boolean equals(Object obj) {
return Objects.equals(value, obj);
}
这不是Entry.equals
. 这可能会将 aEntry
与当前条目保存的值进行比较。(就像比较一封信和一个信封)。
让您的 equals 方法检查obj
是否为Entry
,并获取其值,并检查是否相等。
推荐阅读
- voltdb - VoltDB 9.0 真的支持 Java 11 吗?
- ruby - 如何使用 Nokogiri 从 XML 中检索数据
- selenium-webdriver - 在 Selenium gradle 项目中登录时出现 NullPointerException
- php - 如何在 cakephp 中使用事务?
- r - 无法访问用于生成动态闪亮内容的函数内部的反应对象
- sql - SQL Select: Evenly Distribute Results Set
- spring-boot - Getting "unable to resolve method using strict-mode: org.drools.core.spi.KnowledgeHelper.throw()" when throwing an exception on DRL file
- c++ - Convert function pointer to std::uintptr_t at compile time
- python - 如何扩展一个类,仅当它存在时
- python - 我如何为管道脚本引用 python 包?