java hashCode的介绍


java集合中,判断对象是否相等的规则是:

  (1)判断两个对象的hashCode是否相等,如果不相等,则认为两个对象也不相等。如果相等转入(2

  (2):判断两个对象的equals运算是否相等,如果不相等则认为两个对象也不想等,如果相等认为两个对象相等。

 ============================================================ 
如何理解hashCode的作用:
============================================================ 
java.lang.Object来理解,JVMnew一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这样:
1.new Object(),JVM根据这个对象的Hashcode,放入到对应的Hash表对应的Key,如果不同的对象确产生了相同的hash,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。
2.比较两个对象的时候,首先根据他们的hashcodehash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key,那么他们一定在这个key上的链表上。那么此时就只能根据Objectequal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定他们不能equal.

============================================================   
改写equals时总是要改写hashCode
============================================================
java.lnag.Object中对hashCode的约定:
   1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。
   2. 如果两个对象根据equals(Object o)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
   3. 如果两个对象根据equals(Object o)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。
有一个概念要牢记,两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。
所以hashcode相等只能保证两个对象在一个HASH表里的同一条HASH链上,继而通过equals方法才能确定是不是同一对象,如果结果为true, 则认为是同一对象在插入,否则认为是不同对象继续插入。

重写hashCode equals 方法:

一般使用java中的Map对象进行存储的时候,其会自动调用hashCode方法来比较两个对象是否相等,所以如果对equals 进行重写一定要对hashCode方法进行重写,保证相同的对象返回相同的哈希值,不同的对象返回不同的哈希值。

 如果只重写equals,不重写hashCode ,则hashCode就是继承自Object返回内存编码。这时可能出现equals 相等,而hanhCode不等,你的对象使用集合时,就会等不到正确结果。

 

实例如下:

package com.xiyou.hasCode;

 

public class Person {

   private String name;

   private int age;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public Person(String name, int age) {

super();

this.name = name;

this.age = age;

}

public void setAge(int age) {

this.age = age;

}

   /*

    *  重写hashCode (假如在HashSet中添加相同的数据(相同年龄与姓名)的时候,可以不允许其添加进去 )。

    *  重写HashCode 时应该注意也要重写equals方法

    */

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + ((name == null) ? 0 : name.hashCode());

return result;

}

@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 (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

}

测试类:

/*   hashcode ()方法,在object中定义如下:

 *   public native hashCode ()

 *   是本地方法,其实现与本地机器有关,当然覆盖它

 */

public class HasCode {

     public static void main(String[] args) {

HashSet< Person > set = new HashSet<>();

Person p = new Person("小白", 14);

Person p2 = new Person("小虎",13);

System.out.println("p hashCode="+p.hashCode());

System.out.println("p1 hashCode="+p2.hashCode());

System.out.println("p 的散列值"+p.hashCode()%16);

System.out.println("p1 的散列值"+p2.hashCode()%16);

set.add(p);

set.add(p2);

System.out.println(set.size());

set.add(new Person("小虎",15));

System.out.println(set.size());

}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值