hashCode在比较两个对象时起什么作用?
What role does hashCode play when comparing two objects?
我决定研究 Java 中的一些主要文档。我从 Object
class 开始,我正在查看 equals
方法。我知道 equals
正在使用 hashCode
方法。虽然 hashCode
returns int 所以可以生成的唯一哈希码数量有限。
当我尝试比较具有相同 hashCode
的两个 不同 对象时会发生什么?这甚至可能吗?
是的。两个对象可以具有相同的哈希码。但是,hashcode
在比较两个对象时不起作用。如果要检查 class 的两个对象是否为 equal
,请覆盖 equals
并定义 class 的两个对象何时应被视为相等。如果要比较 class 的一个对象是否比另一个对象少 than/greater(通常在对集合进行排序时),请实现 Comparable
并覆盖 compareTo
方法。 (你也可以实现Comparator
)
如果您想将对象存储在 HashSet
中或将其用作 HashMap
中的键,请确保覆盖 hashCode
方法或您的 objects/keys 很可能会存储在不同的桶中,从而导致重复。
不要忘记覆盖您创建的 class 中的 equals
。如果您不这样做,那么两个对您 class 对象的引用只有在引用同一对象时才相等。
hashcode()
的合同很简单:
如果根据 equals 方法两个对象相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。
不要求如果根据 equals 方法两个对象不相等,则对两个对象中的每一个调用 hashCode 方法必须产生不同的整数结果。
因此,任何 class 个对象的有效哈希函数可以是:
@Override
public int hashcode() {
return 42;
}
满足相等对象具有相同hashcode值的契约。
问题是 class 使用上述哈希码将对象分发到桶中的系统(例如 HashSet
)会将所有对象分发到同一个桶中,从而导致严重的性能后果。最佳哈希函数虽然不是严格要求,但会为不相等的对象生成不同的值,以便将它们分配到自己的桶中。
Object.equals()
的合同在进行比较时不需要使用 hashcode()
。但是,如果不可变对象具有昂贵的相等比较,它可能会使用哈希码值来确定是否需要进行昂贵的比较。哈希码可以在第一次计算时缓存。因为对象是不可变的,哈希码不能改变,所以它可以安全地缓存在实例中。因此哈希码可以用作相等比较的优化:昂贵的比较只需要在具有相同哈希码的实例上进行。
可以在 Effective Java,第 3 版中找到用于编写足够散列函数的简单算法。 (J.布洛赫)。现代IDE的也可以自动为你生成哈希函数。
我决定研究 Java 中的一些主要文档。我从 Object
class 开始,我正在查看 equals
方法。我知道 equals
正在使用 hashCode
方法。虽然 hashCode
returns int 所以可以生成的唯一哈希码数量有限。
当我尝试比较具有相同 hashCode
的两个 不同 对象时会发生什么?这甚至可能吗?
是的。两个对象可以具有相同的哈希码。但是,hashcode
在比较两个对象时不起作用。如果要检查 class 的两个对象是否为 equal
,请覆盖 equals
并定义 class 的两个对象何时应被视为相等。如果要比较 class 的一个对象是否比另一个对象少 than/greater(通常在对集合进行排序时),请实现 Comparable
并覆盖 compareTo
方法。 (你也可以实现Comparator
)
如果您想将对象存储在 HashSet
中或将其用作 HashMap
中的键,请确保覆盖 hashCode
方法或您的 objects/keys 很可能会存储在不同的桶中,从而导致重复。
不要忘记覆盖您创建的 class 中的 equals
。如果您不这样做,那么两个对您 class 对象的引用只有在引用同一对象时才相等。
hashcode()
的合同很简单:
如果根据 equals 方法两个对象相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。
不要求如果根据 equals 方法两个对象不相等,则对两个对象中的每一个调用 hashCode 方法必须产生不同的整数结果。
因此,任何 class 个对象的有效哈希函数可以是:
@Override
public int hashcode() {
return 42;
}
满足相等对象具有相同hashcode值的契约。
问题是 class 使用上述哈希码将对象分发到桶中的系统(例如 HashSet
)会将所有对象分发到同一个桶中,从而导致严重的性能后果。最佳哈希函数虽然不是严格要求,但会为不相等的对象生成不同的值,以便将它们分配到自己的桶中。
Object.equals()
的合同在进行比较时不需要使用 hashcode()
。但是,如果不可变对象具有昂贵的相等比较,它可能会使用哈希码值来确定是否需要进行昂贵的比较。哈希码可以在第一次计算时缓存。因为对象是不可变的,哈希码不能改变,所以它可以安全地缓存在实例中。因此哈希码可以用作相等比较的优化:昂贵的比较只需要在具有相同哈希码的实例上进行。
可以在 Effective Java,第 3 版中找到用于编写足够散列函数的简单算法。 (J.布洛赫)。现代IDE的也可以自动为你生成哈希函数。