Java Object.hashCode()分析

Java中的Object类是所有类的父类,它提供以下方法:
public final native Class<?> getClass()
public native int hashCode()
public boolean equals(Object obj)
protected native Object clone() throws CloneNotSupportedException
public String toString()
public final native void notify()
public final native void notifyAll()
public final native void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
public final void wait() throws InterruptedException
protected void finalize() throws Throwable { }
hashCode()方法
  • 是一个native方法, 该方法返回对象的哈希码(默认情况下,对象的哈希码是通过将该对象的内部地址转换成一个整数来实现的),主要使用在哈希表中,比如HashMap、HashTable、HashSet。

    被native关键字修饰的方法叫做本地方法,本地方法和其它方法不一样,本地方法意味着和平台有关,因此使用了native的程序可移植性都不太高。另外native方法在JVM中运行时数据区也和其它方法不一样,它有专门的本地方法栈。native方法主要用于加载文件和动态链接库

  • 哈希码的通用约定:

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

    • Object类默认equals方法比较的是两个对象的内存地址。
    • 当 equals 方法被重写时,由于要以维护 hashCode 方法的常规协定(即:相等对象必须具有相等的哈希码),通常有必要重写 hashCode 方法。
    • 如果两个对象hashCode值相等(导致两个对象在哈希表中的同意数组项,也就是同一串链表中),但equals不相等,会影响性能。

举例:重写Student的equals方法,使得姓名+年龄+性别相同的学生相等。

	public boolean equals(Object obj) {
		if(!(obj instanceof Student)) {
       // instanceof 已经处理了obj = null的情况
			return false;
		}
		Student stuObj = (Student) obj;
		// 地址相等
		if (this == stuObj) {
			return true;
		}
		// 如果两个对象姓名、年龄、性别相等,我们认为两个对象相等
		if (stuObj.name.equals(this.name) && stuObj.sex.equals(this.sex) && stuObj.age.equals(this.age)) {
			return true;
		} else {
			return false;
		}
	}

如果将两个Student对象放入Map或Set中,不重写hashCode()的时候,相等的对象会同时存在,不会覆盖(因为此时hashCode()不相等,而HashSet的底层是通过HashMap实现的,最终比较set容器内元素是否相等是通过比较对象的hashcode来判断的),所以要同时重写hashCode()。

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

整理出判断对象相等的属性,然后取一个尽可能小的正整数(尽可能小时怕最终得到的结果超出了整型int的取数范围),这里取了17,然后计算17*属性的hashcode+其他属性的hashcode,重复步骤。

【参考文档】
Java根类Object的方法说明
重写hashcode和equals方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值