java中的Hashcode契约?
在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须一致地返回相同的整数 上述声明载于() 根据hashcode合同 我对声明有一个问题,即 如果对象上的equals比较中未使用任何信息 修改 即使我们修改equals方法,hashcode仍然会返回相同的整数。所以为什么散列码的值取决于对象的相等比较。好问题。从 请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码 好问题。从 请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码java中的Hashcode契约?,java,Java,在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须一致地返回相同的整数 上述声明载于() 根据hashcode合同 我对声明有一个问题,即 如果对象上的equals比较中未使用任何信息 修改 即使我们修改equals方法,hashcode仍然会返回相同的整数。所以为什么散列码的值取决于对象的相等比较。好问题。从 请注意,每当重写hashCode方法时,通常都需要重写该方法,以便维护hashCo
这意味着,如果没有修改任何一个对象属性(请参阅:不应被视为瞬态的实例变量),那么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所用属性的严格子集。