Java 非标准equals的hashCode和compareTo

Java 非标准equals的hashCode和compareTo,java,Java,考虑到以下equals的实现: public class Test implements Comparable<Test> { private int x, y; @Override public boolean equals(Object obj) { if (obj instanceof Test) { Test other = (Test) obj; return x == other.x

考虑到以下equals的实现:

public class Test implements Comparable<Test> {
    private int x, y;

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Test) {
            Test other = (Test) obj;
            return x == other.x || y == other.y;
        }
        return false;
    }

    @Override
    public int hashCode() {
        //implementation?
    }

    @Override
    public int compareTo(Test o) {
        //implementation?
    }
}
公共类测试实现了可比较的{
私有整数x,y;
@凌驾
公共布尔等于(对象obj){
if(obj测试实例){
测试其他=(测试)obj;
返回x==other.x | y==other.y;
}
返回false;
}
@凌驾
公共int hashCode(){
//实施?
}
@凌驾
公共整数比较(测试o){
//实施?
}
}
hashCode和compareTo的正确/最高效实现是什么? 请注意-equals使用,而不是

equals()方法用于确定两个对象的相等性

当我们说平等时,它应该遵循以下属性:

自反的:总是a=a。在Java中,a.equals(a)应该始终为true

对称:如果a=b,则b=a。在Java中,如果a.equals(b)为true,那么b.equals(a)应该为true

及物的:如果a=b和b=c,那么a=c。在Java中,如果a.equals(b)和b.equals(c)为真,那么a.equals(c)应该为真

您的equals()不符合此规则

此外,根据javadoc——强烈建议(尽管不是必需的)自然排序与equals一致。这是因为没有显式比较器的排序集(和排序映射)在与自然顺序与equals不一致的元素(或键)一起使用时表现“奇怪”。因此,在自然排序时使用equals()的这个实现可能会遇到一些问题

在Java中重写equals方法的好方法

  • 执行此检查——如果是,则返回true
  • 执行空检查——如果是,则返回false
  • 执行检查的实例
  • 类型强制转换对象
  • 比较从数值属性开始的单个属性,因为比较数值属性很快,并且使用短路运算符组合检查。若第一个字段不匹配,不要尝试匹配属性的其余部分并返回false
  • equals()方法用于确定两个对象的相等性

    当我们说平等时,它应该遵循以下属性:

    自反的:总是a=a。在Java中,a.equals(a)应该始终为true

    对称:如果a=b,则b=a。在Java中,如果a.equals(b)为true,那么b.equals(a)应该为true

    及物的:如果a=b和b=c,那么a=c。在Java中,如果a.equals(b)和b.equals(c)为真,那么a.equals(c)应该为真

    您的equals()不符合此规则

    此外,根据javadoc——强烈建议(尽管不是必需的)自然排序与equals一致。这是因为没有显式比较器的排序集(和排序映射)在与自然顺序与equals不一致的元素(或键)一起使用时表现“奇怪”。因此,在自然排序时使用equals()的这个实现可能会遇到一些问题

    在Java中重写equals方法的好方法

  • 执行此检查——如果是,则返回true
  • 执行空检查——如果是,则返回false
  • 执行检查的实例
  • 类型强制转换对象
  • 比较从数值属性开始的单个属性,因为比较数值属性很快,并且使用短路运算符组合检查。若第一个字段不匹配,不要尝试匹配属性的其余部分并返回false

  • 这不仅是一个“非标准”的equals实现,而且是一个无效的equals实现,因为它不是可传递的——如果
    a.x=1
    a.y=2
    b.x=3
    c.x=3
    c.y=4
    那么
    a.equals(b)
    b.equals(c)
    但是
    a
    c
    不相等。同意。你在自找麻烦!另外,作为一般规则,根据
    compareTo
    的等式应与根据
    equals
    的等式相同,否则您将在排序的集合中遇到错误。对于hashCode,黄金法则是,如果它们相等,您只需给出相同的hashCode值,如果它们不同,则无所谓。。但是如果在这种情况下不是相同的hashcode,那就更好了lol(以避免hashSet或hashMaps中的冲突)。。。虽然唯一可能与(有缺陷的)
    equals
    一致的
    hashCode
    实现是将相同的哈希代码分配给每个对象的退化实现。请看,这不仅是一个“非标准”equals实现,而且是无效的,因为它不是可传递的-如果
    a.x=1
    a.y=2
    b.x=3
    b.y=2
    c.x=3
    c.y=4
    然后
    a.equals(b)
    b.equals(c)
    但是
    a
    c
    彼此不相等。同意。你在自找麻烦!另外,作为一般规则,根据
    compareTo
    的等式应与根据
    equals
    的等式相同,否则您将在排序的集合中遇到错误。对于hashCode,黄金法则是,如果它们相等,您只需给出相同的hashCode值,如果它们不同,则无所谓。。但是如果在这种情况下不是相同的hashcode,那就更好了lol(以避免hashSet或hashMaps中的冲突)。。。尽管唯一可能与(有缺陷的)
    equals
    一致的
    hashCode
    实现是为每个对象分配相同哈希代码的退化实现。请参阅