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

iXô*_*iXô 1 java dictionary hashmap

我想将数据存储在地图中,关键是单一,但我希望地图使用我的密钥类的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 11

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

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

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

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

x    400
y   1200
z   2000
Run Code Online (Sandbox Code Playgroud)

根据你的描述,x.equals(y)这是真的,y.equals(z)是真的,但是x.equals(z)会是假的,从而违反了合同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.