Object中的hashCode以及String的HashCode

一,HashCode的作用

什么是hashCode:由对象,导出的一个整型值。

作用:为了提供查找的快捷性,用于在散列结构中,存储对象在Hash表中的地址。

 二,重写了equals()方法,为何要重写hashcode()方法?

hashcode的源码说明,hashcode要满足以下条件:

<ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>

1.  在java应用程序运行时,无论何时多次调用同一个对象时的hsahCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值

2.  如果两个对象equals()返回值为true,则他们的hashCode()也必须返回相同的int值

3.  如果两个对象equals()返回值为false,则他们的hashCode()返回值也必须不同

举个例子:

public class Test {
    public static void main(String[] args) {
        String string =  new String("a");
        String string2 =  new String("a");
        
        System.out.println("内存地址比较结果:"+(string == string2));
        System.out.println("值比较结果"+string.equals(string2));
    }
}

输出结果:

内存地址比较结果:false
值比较结果true
 

分析:由于String重写了equals方法,可以看到值equals方法的 比较结果为true;而使用==比较,是比较内存地址,显然是两个不同的对象,也就有不同的地址,如果不重写hashcode方法,那么hashcode的值,也将会是默认值:内存地址。这时候,hashcode的值就不相等了,这时候,就不符合上述第二条规则。

三,拓展:为何String类型hashcode 计算式,选择31?

先看看源码:

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

直接原因吧:

1,JVM优化,31 = (2<<5)-1,JVM做了这个计算的优化,效率高。

2,31 为素数,可以减少冲突

3,31数字不是很大,也不是很小,可以减少冲突,并且不会溢出。

参考博客:https://www.cnblogs.com/nullllun/p/8350178.html

四,重写一个类的equals和hashcode方法示例:

package com.blog.spring.test;

public class Person {

    private String name;
    private int age;

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        
        Person other = (Person) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
}
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值