是否存在使用 equals 方法进行密钥检查的地图?
Does a map using equals method for key checking exists?
我想在地图中存储数据,键唯一性,但我希望地图使用我的键的 equals 方法 class。
HashMap 好像没有使用equals 方法(我可能错了,如果是这样我的测试是错误的)。
我的问题是地图使用 hashCode 来检查重复项,我想要一个使用 equals 的地图实现。
我将时间戳存储在密钥中,如果时间戳差异不超过定义的量(比如 1000 毫秒),我想使 2 个密钥相等。
编辑:代码
public class CleanKey
{
private DateTime start;
private DateTime end;
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((end == null) ? 0 : end.hashCode());
result = prime * result + ((start == null) ? 0 : start.hashCode());
return result;
}
public boolean equals(Object obj)
{
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
CleanKey other = (CleanKey) obj;
if(end == null)
{
if(other.end != null)
return false;
}
else if(Math.abs(Millis.millisBetween(end, other.end).getMillis()) > 1000)
return false;
if(start == null)
{
if(other.start != null)
return false;
}
else if(Math.abs(Millis.millisBetween(start, other.start).getMillis()) > 1000)
return false;
return true;
}
}
您需要重写您的 hashCode 和 equals class。
此处:Understanding the workings of equals and hashCode in a HashMap
看到代码后编辑:
Hashcode 是 returning 错误的值,因为您正在使用结束字段来计算散列...不同的结束导致不同的散列。
试一试...return一个常量,hashmap 就可以工作
It seems that HashMap doesn't use the equals method (I may be wrong, if so my tests are wrong).
确实使用了equals
,但它首先使用了hashCode
。它只会在具有相同散列码的键上调用 equals
- 这就是它如何提高效率的方式。这不是问题,只要您的 hashCode
和 equals
方法遵守 java.lang.Object
.
中指定的合同
I am storing timestamp in the key, and would like to make it so that 2 keys are equals if there timestamp difference does not exceed a defined amount (let say 1000 ms).
你不能那样做。它违反了平等契约,因为你不能有传递性。假设我们有三个具有以下时间戳的键 x、y 和 z:
x 400
y 1200
z 2000
根据你的描述,x.equals(y)
为真,y.equals(z)
为真,x.equals(z)
为假,违反了Object.equals
的约定。
The equals method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value x, x.equals(x) should return true.
- It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
- It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
- It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
- For any non-null reference value x, x.equals(null) should return false.
我想在地图中存储数据,键唯一性,但我希望地图使用我的键的 equals 方法 class。
HashMap 好像没有使用equals 方法(我可能错了,如果是这样我的测试是错误的)。
我的问题是地图使用 hashCode 来检查重复项,我想要一个使用 equals 的地图实现。
我将时间戳存储在密钥中,如果时间戳差异不超过定义的量(比如 1000 毫秒),我想使 2 个密钥相等。
编辑:代码
public class CleanKey
{
private DateTime start;
private DateTime end;
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((end == null) ? 0 : end.hashCode());
result = prime * result + ((start == null) ? 0 : start.hashCode());
return result;
}
public boolean equals(Object obj)
{
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
CleanKey other = (CleanKey) obj;
if(end == null)
{
if(other.end != null)
return false;
}
else if(Math.abs(Millis.millisBetween(end, other.end).getMillis()) > 1000)
return false;
if(start == null)
{
if(other.start != null)
return false;
}
else if(Math.abs(Millis.millisBetween(start, other.start).getMillis()) > 1000)
return false;
return true;
}
}
您需要重写您的 hashCode 和 equals class。
此处:Understanding the workings of equals and hashCode in a HashMap
看到代码后编辑:
Hashcode 是 returning 错误的值,因为您正在使用结束字段来计算散列...不同的结束导致不同的散列。
试一试...return一个常量,hashmap 就可以工作
It seems that HashMap doesn't use the equals method (I may be wrong, if so my tests are wrong).
确实使用了equals
,但它首先使用了hashCode
。它只会在具有相同散列码的键上调用 equals
- 这就是它如何提高效率的方式。这不是问题,只要您的 hashCode
和 equals
方法遵守 java.lang.Object
.
I am storing timestamp in the key, and would like to make it so that 2 keys are equals if there timestamp difference does not exceed a defined amount (let say 1000 ms).
你不能那样做。它违反了平等契约,因为你不能有传递性。假设我们有三个具有以下时间戳的键 x、y 和 z:
x 400
y 1200
z 2000
根据你的描述,x.equals(y)
为真,y.equals(z)
为真,x.equals(z)
为假,违反了Object.equals
的约定。
The equals method implements an equivalence relation on non-null object references:
- It is reflexive: for any non-null reference value x, x.equals(x) should return true.
- It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
- It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
- It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
- For any non-null reference value x, x.equals(null) should return false.