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

时间:2015-08-06 15:58:26

标签: java dictionary hashmap

我想将数据存储在地图中,关键是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;
    }
}

2 个答案:

答案 0 :(得分:11)

  

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

确实使用equals,但它首先使用hashCode。它只会在具有相同哈希码的密钥上调用equals - 这就是它如何有效地工作。只要您的hashCodeequals方法遵守java.lang.Object中指定的合同,这就不是问题。

  

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

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

x    400
y   1200
z   2000

根据您的说明,x.equals(y)为真,y.equals(z)为真,但x.equals(z)为假,因此违反了Object.equals的合同。

  

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

     
      
  • reflexive :对于任何非空引用值x,x.equals(x)应返回true。
  •   
  • 对称:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)才应返回true。
  •   
  • transitive :对于任何非空引用值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。
  •   

答案 1 :(得分:0)

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

此处:Understanding the workings of equals and hashCode in a HashMap

看到代码后编辑:

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

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