牛叔叔 的笔记

好好学习

2023-07-30 11:10

哈希码(Hash code)是什么?

牛叔叔

JavaEE

(2287)

(0)

收藏

哈希码(Hash code)是一种用于唯一标识对象的整数值。它是根据对象的内容生成的,可以将对象映射到一个固定大小的索引或地址,在哈希表和哈希函数等数据结构和算法中被广泛应用。

哈希码的计算通常包括以下几个特点:

  1. 一致性:在对象的生命周期中,无论何时调用hashCode方法,得到的值应该是相同的,除非对象内部的属性发生了变化。

  2. 相等性:对于相等的对象,它们应该具有相同的哈希码。然而,哈希码相等并不意味着对象一定相等。

  3. 均匀性:哈希码的分布应该尽可能均匀,避免不同对象生成相同的哈希码(即哈希冲突)。

在Java中,默认情况下,Object类的hashCode方法会根据对象的内存地址生成哈希码。因此,不同对象的哈希码通常是不相等的,即使它们的内容相同。

如果在自定义的类中需要使用hashCode方法,通常需要重写hashCode方法来满足一致性和相等性的要求。一个常见的计算方式是基于对象的属性值,可以根据以下原则进行计算:

  1. 选择一个非零常数,通常是一个质数,作为计算的初始值。

  2. 对于对象的每个重要属性,计算它们的哈希码并结合计算得到的哈希码,可以使用乘法、加法或位运算等方式。

  3. 最后,返回计算得到的哈希码作为对象的hashCode值。

需要注意的是,在重写hashCode方法时,还需要重写equals方法,以确保对象的相等性判断是正确的。

在Java中,很多类已经重写了hashCode方法,比如String、Integer等。对于自定义的类,如果需要在集合类中使用,建议重写hashCode方法以确保正确性和性能。


当我们创建一个自定义的类,比如Student类,希望能够正确使用集合类时,就需要重写hashCode和equals方法。下面是一个示例的Student类,展示了如何实现合适的hashCode和equals方法:

public class Student {
    private String name;
    private int age;
    private String id;

    public Student(String name, int age, String id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        result = 31 * result + age;
        result = 31 * result + id.hashCode();
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        Student other = (Student) obj;
        return name.equals(other.name) && age == other.age && id.equals(other.id);
    }}

在上面的示例中,hashCode方法根据Student对象的name、age和id属性计算哈希码。使用了常数31作为乘法的基数,这个基数的选择是为了保持计算结果的性能和均匀性。

equals方法比较了两个Student对象的name、age和id属性是否相等,如果三个属性都相等,则返回true;否则返回false。

重写了hashCode和equals方法后,我们可以在使用集合类(如HashMap、HashSet等)时,确保Student对象能够正确地用作键(key)或者比较对象唯一性。


在hashCode方法的实现中,选择初始值和乘法因子的具体数值是为了达到一定的随机性和均匀性,以减少哈希冲突的概率。

初始值(initial value)通常选择一个非零的素数,比如17。这是因为素数在乘法运算中具有较好的性质,能够帮助减少哈希冲突的可能性。

乘法因子(multiplicative factor)通常选择一个较大的素数,比如31。这个选择是基于数学分析和经验,在大多数情况下,31这个数的表现比其他数更好,能够生成更好的结果,减少相同属性值不同对象的哈希冲突。

在计算哈希码时,通过对属性的哈希值进行乘法操作,并结合之前计算得到的结果,使得对象的不同属性可以彼此影响,增加了哈希码的随机性。

需要注意的是,这里选择的特定数值并非固定的规则,不同的实现可能存在一些调整和优化。根据具体情况,可以选择适合自己需求的初始值和乘法因子。但总体原则是,初始值和乘法因子应该是非零的素数,并经过一定测试和验证,确保生成的哈希码具有较好的性能和分布特性。


0条评论

点击登录参与评论