为什么重写equals还要重写hashcode

为什么重写equals还要重写hashcode

1)简介

equals和hashcode都属于Object类的方法,其中hashcode为本地方法。

object中equals是比较是否为同一对象。

 public boolean equals(Object obj) {
        return (this == obj);
    }

object中hashcode是得到对象得hash值。

public native int hashCode();

String对equals和hashcode的重写:

String中的equals

1.同一对象 (true)

2.同一类型&&长度相等&&值相等 ( true)

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

String中的hashcode

根据对象的值计算出一个int类型的数值。

 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;

2)equals和hashcode的联系

java对两者有以下规范:

  1. equals相等,hashcode必定相等;
  2. hashcode相等,equals未必相等;

3)为什么重写equals必须重写hashcode

1.编写一个Student类,不重写equals和hashcode方法

public class Student {
private String name;
private int age;

public Student(String name, int age) {
	this.name = name;
	this.age = age;
}
    ...省略set,get方法
}

public static void main(String[] args) {
	Student s1 = new Student("lisi",12);
	Student s2 = new Student("lisi",12);
	System.out.println(s1.equals(s2));
	System.out.println("s1:"+s1.hashCode());
	System.out.println("s2:"+s2.hashCode());
}
}

结果:

因为s1,s2为两个不同实例所以equals和hashcode都不想等。

false
s1:118352462
s2:1550089733

2.重写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;
	Student other = (Student) obj;
	if (name == null) {
		if (other.name != null)
			return false;
	} else if (!name.equals(other.name))
		return false;
	return true;
}

结果:

equals和hashcode都相等。

true
s1:3322034
s2:3322034

3.重写equals,不重写hashcode

@Override
public boolean equals(Object obj) {
	if (this == obj)
		return true;
	if (obj == null)
		return false;
	if (getClass() != obj.getClass())
		return false;
	Student other = (Student) obj;
	if (name == null) {
		if (other.name != null)
			return false;
	} else if (!name.equals(other.name))
		return false;
	return true;
}

结果:

equals相等而hashcode不相等,违背java规范这是一个原因。

true
s1:118352462
s2:1550089733

原因之二:

hash类存储结构(HashSet、HashMap等等)添加元素会有重复性校验,校验的方式就是先取hashCode判断是否相等(找到对应的位置,该位置可能存在多个元素),然后再取equals方法比较(极大缩小比较范围,高效判断),最终判定该存储结构中是否有重复元素

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值