浅谈HashCode

作用:

 返回该对象的hashcode值,作用为了提高查询效率,为了配合散列的集合一起使用,类似于这样的散列集合有,hashset,hashmap,hashtable

哈希码的通用约定如下:

在java程序执行过程中,在一个对象没有被改变的前提下,无论这个对象被调用多少次,hashCode方法都会返回相同的整数值。对象的哈希码没有必要在不同的程序中保持相同的值。
如果2个对象使用equals方法进行比较并且相同的话,那么这2个对象的hashCode方法的值也必须相等。
如果根据equals方法,得到两个对象不相等,那么这2个对象的hashCode值不需要必须不相同。但是,不相等的对象的hashCode值不同的话可以提高哈希表的性能。
 

通常情况下,不同的对象产生的哈希码是不同的。默认情况下,对象的哈希码是通过将该对象的内部地址转换成一个整数来实现的。

源码:

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;
    }

hashcode在hashmap中的应用

当你往集合里插入一个对象,散列集合是不允许重复的元素存在,先调用找个对象的hashcode方法,得到hashcode值,以hashmap为例,具体实现中会以有一个table来存储已经存进去对象的hashcode值,如果table里面没有该hashcode值,就直接存进去了,如果存在,就调用eq方法,相同就不存了,覆盖掉value值,hashcode方法的存在就是为了减少eq方法的调用次数,提高程序效率

       //只重写了hashcode方法
        Person a = new Person("a");
        Person b = new Person("b");
        HashMap<Object, Object> map = new HashMap<>();
        map.put(a,"f1");
        map.put(b,"f2");
        System.out.println("map = " + map);



//结果如下


//map = {Person{name='b'}=f2, Person{name='a'}=f1}

上面代码中,hashmap中存入了a,b两个对象,但是这2个元素是在哈希表中的同一个数组项中的位置,也就是在同一串链表中。为什么,a和b的hashcode值相同,但是确存入到了map中,因为hashmap判断重复数据的条件是 两个对象的hash码相同,且eq方法比较得到的结果为true

这个时候如果再重写eq方法,得到的就只有一个对象了。

相同对象的hashcode值不一定相同,相同hashcode值的对象不一定是相同对象

两个对象的hashcode值不同,那么一定是两个不同的对象

两个对象的eq方法不同,hashcode值一定不同

两个对象的eq方法相同,hashcode值也一定相同,否则就违背了违反了通用约定的第二点

重写eq方法的同时必须重写hashcode方法

 创建了一个对象,new person( jack ),把他存入hashmap里,值为18,使用hashmap.get(new person( jack )) ,正常情况下,如果两个person对象,值都一样,则认为是同一个, 在这里的意愿是想输出存入的1,事实上得到的结果为null

要知道默认情况下,hashcode方法是将对象的存储地址进行映射,

new person( jack ) 和 hashmap.get(new person( jack )) 生成的是2个对象,他们的存储地址不同,先进行了hashcode运算,也是有几率会两个对象的hashcode是一样的, 这样的几率非常小,

 

设计hashcode的重要因素:: 无论何时,对同一个对象调用hashcode都应该产生相同的,如果一个对象用put添加进hashmap时产生一个hashcode值,get取出的时候产生了另一个hashcode值,就无法获取该对象,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值