HashSet 没有意识到两个对象是相同的
HashSet does not realize that two objects are the same
我看过其他几次在 Whosebug 上提出这个问题,但 none 其他用例似乎解决了我的问题。 HashSet does not seem to realize that two objects are the same.
基本上,这是我的class。
private static class Inconsistency
{
int a;
int b;
boolean isConsistency;
//Default constructor. To be used when we don't have an inconsistency
public Inconsistency()
{
this.a = -1;
this.b = -1;
this.isConsistency = false;
}
public Inconsistency(int a, int b, boolean isConsistency)
{
this.a = a;
this.b = b;
this.isConsistency = isConsistency;
}
@Override
public String toString()
{
if (this.isConsistency)
{
return "(" + this.a + ", " + this.b + ")";
}
else
{
return "No inconsistency";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
result = prime * result + b;
result = prime * result + (isConsistency ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
if (this.getClass() != other.getClass())
{
return false;
}
Inconsistency otherInconsistency = (Inconsistency) other;
return ((this.a == otherInconsistency.a) && (this.b == otherInconsistency.b) && (this.isConsistency == otherInconsistency.isConsistency))
|| ((this.a == otherInconsistency.b) && (this.b == otherInconsistency.a) && (this.isConsistency == otherInconsistency.isConsistency));
}
}
我正在尝试将 class 的对象存储在哈希图中。
按照我定义 equals 方法的方式,一个不一致 A (10, 20, true) 应该等于另一个不一致 B (20, 10, true),当我测试我的 equals 方法时,这个工作正常。但是,当我尝试将 A 和 B 都插入 HashSet 时,它们都被错误地添加了。我知道我应该操纵我的哈希码函数,但我不确定如何去做。
这是一个展示错误行为的驱动程序
Inconsistency A = new Inconsistency(10,20, true);
Inconsistency B = new Inconsistency(20,10, true);
System.out.println(A.equals(B)); // prints true as expected
HashSet<Inconsistency> test = new HashSet<>();
test.add(A);
test.add(B);
System.out.println(test); // prints [(10, 20), (20, 10)]. The two objects are equal but are both added to hashset
所以问题很明确,我如何确保两个相等的对象 A 和 B 都不会添加到我的 HashSet 中?
您对 equals
的定义意味着两个 Inconsistency
元素颠倒的对象是 .equals
,但您对 hashCode
的定义 不是 return 如果 a
和 b
的顺序不同,则相同的哈希码,如果 HashSet
或其他基于哈希的集合是为了正常工作。
解决此问题的最简单方法是做一些可交换的事情——无论 a
和 b
的顺序如何,结果都相同。例如:
result = prime * result + a + b;
而不是
result = prime * result + a;
result = prime * result + b;
我看过其他几次在 Whosebug 上提出这个问题,但 none 其他用例似乎解决了我的问题。 HashSet does not seem to realize that two objects are the same.
基本上,这是我的class。
private static class Inconsistency
{
int a;
int b;
boolean isConsistency;
//Default constructor. To be used when we don't have an inconsistency
public Inconsistency()
{
this.a = -1;
this.b = -1;
this.isConsistency = false;
}
public Inconsistency(int a, int b, boolean isConsistency)
{
this.a = a;
this.b = b;
this.isConsistency = isConsistency;
}
@Override
public String toString()
{
if (this.isConsistency)
{
return "(" + this.a + ", " + this.b + ")";
}
else
{
return "No inconsistency";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
result = prime * result + b;
result = prime * result + (isConsistency ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object other)
{
if (this == other)
{
return true;
}
if (other == null)
{
return false;
}
if (this.getClass() != other.getClass())
{
return false;
}
Inconsistency otherInconsistency = (Inconsistency) other;
return ((this.a == otherInconsistency.a) && (this.b == otherInconsistency.b) && (this.isConsistency == otherInconsistency.isConsistency))
|| ((this.a == otherInconsistency.b) && (this.b == otherInconsistency.a) && (this.isConsistency == otherInconsistency.isConsistency));
}
}
我正在尝试将 class 的对象存储在哈希图中。
按照我定义 equals 方法的方式,一个不一致 A (10, 20, true) 应该等于另一个不一致 B (20, 10, true),当我测试我的 equals 方法时,这个工作正常。但是,当我尝试将 A 和 B 都插入 HashSet 时,它们都被错误地添加了。我知道我应该操纵我的哈希码函数,但我不确定如何去做。
这是一个展示错误行为的驱动程序
Inconsistency A = new Inconsistency(10,20, true);
Inconsistency B = new Inconsistency(20,10, true);
System.out.println(A.equals(B)); // prints true as expected
HashSet<Inconsistency> test = new HashSet<>();
test.add(A);
test.add(B);
System.out.println(test); // prints [(10, 20), (20, 10)]. The two objects are equal but are both added to hashset
所以问题很明确,我如何确保两个相等的对象 A 和 B 都不会添加到我的 HashSet 中?
您对 equals
的定义意味着两个 Inconsistency
元素颠倒的对象是 .equals
,但您对 hashCode
的定义 不是 return 如果 a
和 b
的顺序不同,则相同的哈希码,如果 HashSet
或其他基于哈希的集合是为了正常工作。
解决此问题的最简单方法是做一些可交换的事情——无论 a
和 b
的顺序如何,结果都相同。例如:
result = prime * result + a + b;
而不是
result = prime * result + a;
result = prime * result + b;