是否存在使用equals方法进行密钥检查的地图?

我想将数据存储在地图中,关键是unicity,但我希望地图使用我的密钥类的equals方法。

似乎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; } } 

似乎HashMap不使用equals方法(我可能错了,如果是这样我的测试是错误的)。

它确实使用equals ,但它首先使用hashCode 。 它只会打扰使用相同的哈希码调用密钥上的equals – 这就是它如何设法有效。 只要您的hashCodeequals方法遵守java.lang.Object指定的契约,这就不是问题。

我在密钥中存储时间戳,并且如果时间戳差异不超过定义的量(假设1000毫秒),则希望使2个密钥等于。

你不能这样做。 它违反了平等合同,因为你不具备传递性。 假设我们有三个密钥x,y和z,并带有以下时间戳:

 x 400 y 1200 z 2000 

根据您的描述, x.equals(y)将为true, y.equals(z)将为true,但x.equals(z)将为false,从而违反Object.equals的约定。

equals方法在非null对象引用上实现等价关系:

  • 它是自反的 :对于任何非空引用值x,x.equals(x)应该返回true。
  • 它是对称的 :对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
  • 它是传递性的 :对于任何非空引用值x,y和z,如果x.equals(y)返回true而y.equals(z)返回true,则x.equals(z)应返回true。
  • 它是一致的 :对于任何非空引用值x和y,x.equals(y)的多次调用始终返回true或始终返回false,前提是没有修改对象的equals比较中使用的信息。
  • 对于任何非空引用值x,x.equals(null)应返回false。

你需要在你的类中覆盖hashCode和equals。

这里: 了解HashMap中equals和hashCode的工作原理

看到代码后编辑:

Hashcode返回错误的值,因为您使用结束字段来计算哈希值…不同的结尾导致不同的哈希值。

只是尝试…返回一个常量,hashmap将起作用