java中的Hashcode契约?

java中的Hashcode契约?,java,Java,在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须一致地返回相同的整数 上述声明载于() 根据hashcode合同 我对声明有一个问题,即 如果对象上的equals比较中未使用任何信息 修改 即使我们修改equals方法,hashcode仍然会返回相同的整数。所以为什么散列码的值取决于对象的相等比较。好问题。从 请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCo

在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须一致地返回相同的整数

上述声明载于() 根据hashcode合同

我对声明有一个问题,即

如果对象上的equals比较中未使用任何信息 修改

即使我们修改equals方法,hashcode仍然会返回相同的整数。所以为什么散列码的值取决于对象的相等比较。

好问题。从

请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码

好问题。从

请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码


这意味着,如果没有修改任何一个对象属性(请参阅:不应被视为瞬态的实例变量),那么equals应该给出相同的结果,hashcode应该相应地进行操作(对于对象来说是相同的)

实例:

class Pair {
   public int x, y;
   public int hashCode(); // computes hashcode based on both x and y
}

Pair p = new Pair(3,10);
int h1 = p.hashCode();
// program does something but pair is still (3,10)
int h2 = p.hashCode();
assert(h1 == h2)

其原理是,如果比较结果发生变化,则哈希代码必须发生变化,反之亦然。这通常意味着,在计算哈希代码时,应考虑比较两个项目时考虑的所有变量,因此,如果某些内容发生变化,则此变化将在比较和哈希代码上重新反映。

这意味着,如果没有任何对象属性(请参阅:不应被视为瞬态的实例变量)被修改,那么equals应该给出相同的结果,hashcode应该相应地运行(对于对象是相同的)

实例:

class Pair {
   public int x, y;
   public int hashCode(); // computes hashcode based on both x and y
}

Pair p = new Pair(3,10);
int h1 = p.hashCode();
// program does something but pair is still (3,10)
int h2 = p.hashCode();
assert(h1 == h2)

其原理是,如果比较结果发生变化,则哈希代码必须发生变化,反之亦然。这通常意味着,在计算哈希代码时,应考虑比较两个项目时考虑的所有变量,因此,如果某些内容发生变化,则此变化将在比较和h上反映出来ashcodes.

您正在为不存在的语句添加额外的含义。它并不是说,如果equals的求值发生变化,hashCode将发生变化。它是说,如果equals的求值发生变化,hashCode可能会发生变化。以后不再保证hashCode是相同的。它是n如果仍然是,那就错了

记得吗

@Override
public int hashCode() {
    return 1;
}
是hashCode()的一个完全合法的实现,它满足文档中规定的所有要求。根据定义,hashCode不依赖于equals计算

在实践中,它们当然会耦合在一起。通常情况下,您会使用equals中使用的所有相同字段重写hashcode,因为equals为true的两个不同对象必须具有相同的hashcode。并且返回1;对于任何实际依赖hashcode()方法的类来说都不会起到很好的作用

这是一个更完整的hashCode合法实现的示例,它有时会在equals改变时改变,但并不总是如此,这可能更清楚

public class MakesHashMapsSlow {

    private String value;
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final MakesHashMapsSlow other = (MakesHashMapsSlow) obj;
        if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
            return false;
        }
        return true;
    }
    @Override
    public int hashCode() {
        if (value == null || value.isEmpty()) {
            return 0;
        } else {
            return value.charAt(0);
        }
    }
}

您正在为不存在的语句添加额外的含义。它并没有说,如果equals的求值发生变化,hashCode将发生变化。它是说,如果equals的求值发生变化,hashCode可能会发生变化。不再保证以后hashCode会相同。如果我现在仍然是

记得吗

@Override
public int hashCode() {
    return 1;
}
是hashCode()的一个完全合法的实现,它满足文档中规定的所有要求。根据定义,hashCode不依赖于equals计算

在实践中,它们当然会耦合在一起。通常情况下,您会使用equals中使用的所有相同字段重写hashcode,因为equals为true的两个不同对象必须具有相同的hashcode。并且返回1;对于任何实际依赖hashcode()方法的类来说都不会起到很好的作用

这是一个更完整的hashCode合法实现的示例,它有时会在equals改变时改变,但并不总是如此,这可能更清楚

public class MakesHashMapsSlow {

    private String value;
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final MakesHashMapsSlow other = (MakesHashMapsSlow) obj;
        if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
            return false;
        }
        return true;
    }
    @Override
    public int hashCode() {
        if (value == null || value.isEmpty()) {
            return 0;
        } else {
            return value.charAt(0);
        }
    }
}

如此简化,这意味着hashcode和equals应该使用完全相同的属性来确定其结果?即,如果hashcode仅基于“id”进行计算,那么equals将仅基于“id”检查相等。更好的说法是hashcode应该使用equals所用属性的严格子集。如此简化,这意味着ns hashcode和equals是否应该使用完全相同的属性来确定其结果?即,如果hashcode仅基于“id”进行计算,那么equals将仅基于“id”检查相等性更好的说法是hashcode应该使用equals所用属性的严格子集。