对hashCode的一点简单认识

本文介绍了Java中通过equals()方法和hashCode()方法判断对象对等的实现方式。equals()方法用于比较两个对象的内容是否相同,而hashCode()方法则提供了一个唯一的整数表示对象。当两个对象相等时,它们的hashCode()也应该返回相同的值。

hashcode,一个不太好理解,也常被我们忽视的一个概念。然而,hashcode还有对我们有用的东西。
java给我们提供了两种判断对象对等的方式。如果我们判断两个对象是否相等,那么直接用“==”运算就可以了。然而,判断两个对象对等,就没有那么简单了。
在java中,我们常常通过equals()方法来判断两个对象的对等。其实,我么还可以通过hashCode()来判断两个对象的对等。

看下面的例子:

import java.util.List;

public class MyBag{
    float money;
    List books;  
}
我们如何判断两个MyBag对象是对等的呢?也就是说,如果有两个MyBag的对象bag1和bag2,通过什么的办法能说明这个两个对象是相同的呢?
先声名两个概念:
两个对象相等,指的是,两个引用指向了同一个对象,也就是说,指向了内存中的同一个地址。
两个对象相同(对等),指得是两个对象的任何属性都相等,但是,不是一个对象。

所以,对于上面的MyBag的对象对等,那么,两个对象的money要一样,同时,books要对等。那么如何去判断呢?我们通常会自己去实现equals()方法去判断,方法如下:

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final MyBag other = (MyBag) obj;
        if (books == null) {
            if (other.books != null)
                return false;
        } else if (!books.equals(other.books))
            return false;
        if (Float.floatToIntBits(money) != Float.floatToIntBits(other.money))
            return false;
        return true;
    }

我们也可以通过实现hashCode()来实现:
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((books == null) ? 0 : books.hashCode());
        result = prime * result + Float.floatToIntBits(money);
        return result;
    }

那么我们判断两个对象对等时,就可以这样来实现了:
if(bag1.equals(bag2)){
    // 对等
}

或者
if(bag1.haseCode()==bag2.hashCode()){
    // 对等
}

为什么这种方式也能判断两个对象对等呢?
因为,任何一个对象的hashCode是唯一的,并且和气对象属性按照一定的规则相关的。

比如,一个Integer的hashCode值就是其整数值,因为Integer的haseCode()是这样实现的:
    public int hashCode() {
        return value;
    }
    public boolean equals(Object obj) {
        if (obj instanceof Integer)
            return value == ((Integer) obj).intValue();
        else
            return false;
    }

由此可以看到,也对象的HashCode是和其属性有一定的联系,规则和属性的值有一定的联系,这个规则决定了有相同的hashcode,就有两个对象的属性对等。

http://www.blogjava.net/zhyiwww/archive/2008/04/22/194845.html

在编程中,`hashCode` 的作用主要体现在以下几个方面: 1. **提高查找效率**:`hashCode` 方法的主要目的是生成对象的哈希码,这个哈希码是一个整数,用于在哈希表中快速定位对象的存储位置。通过哈希码,哈希表可以直接计算出对象应该存储在哪个桶(或索引位置)中,从而避免了线性搜索的复杂度和时间开销。此外,在哈希表中查找对象时,首先使用 `hashCode` 方法生成的哈希码来确定可能的存储位置。如果哈希码不同,则对象一定不在同一个桶中,从而避免了不必要的 `equals` 方法调用。 2. **处理哈希冲突**:虽然 `hashCode` 方法可以快速定位对象的存储位置,但不同的对象可能会产生相同的哈希码,这被称为哈希冲突。哈希集合通过链表或其他数据结构来处理这种冲突,确保正确存储和检索对象。当发生哈希冲突时,会调用对象的 `equals` 方法来进一步确定对象是否相等。合理的 `hashCode` 实现可以减少哈希冲突的发生概率。例如,通过结合对象的多个属性来计算哈希码,或者使用高质量的哈希函数,可以降低不同对象产生相同哈希码的可能性。 3. **数据一致性和正确性**:Java 规范要求,如果两个对象通过 `equals` 方法比较结果为 `true`,那么它们的 `hashCode` 方法也必须返回相同的整数。这是为了确保在使用哈希集合等数据结构时,对象的相等性和哈希码的一致性得到正确处理。同时,在同一个对象上多次调用 `hashCode` 方法时,必须始终返回相同的整数(前提是对象的 `equals` 比较中所用的信息没有被修改)。遵循 `hashCode` 的一致性要求可以确保哈希集合等数据结构的正确性和可维护性。如果 `hashCode` 方法的实现不符合要求,可能会导致哈希集合中出现错误的行为,如无法正确存储或检索对象。 4. **分布式系统和数据分区**:在分布式系统中,`hashCode` 可以用于将数据分布到不同的节点或服务器上。通过对数据对象的哈希码进行计算,可以确定数据应该存储在哪个节点上,从而实现数据的分布式存储和处理。类似地,在一些数据分区的场景中,`hashCode` 可以用于确定数据属于哪个分区,以便进行高效的数据管理和处理。 ### 示例代码 以下是一个简单的 Java 示例,展示了如何重写 `hashCode` 和 `equals` 方法: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; if (age != person.age) return false; return name != null ? name.equals(person.name) : person.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } } ``` 在这个例子中,`hashCode` 方法结合了 `name` 和 `age` 属性来生成哈希码,确保了对象的唯一性和一致性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值