为什么重写equals方法一定要重写hashcode方法

为什么重写equals方法一定要重写hashcode方法

先来看看如果重写类的equals方法,但是没有重写hashcode方法会发生什么。

例如:
重写了一个类HashTest的equals方法,但是没有重写HashTest的hashCode方法,它的两个对象A和B逻辑上比较是正确的。

在插入操作中

将A和B作为key放入HashMap中(一般放在key的是String),先调用A和B的hashcode方法来确定存放在那里。
因为没有重写hashcode方法,自动调用原生的Object的hashcode,这样就使得A和B产生不同的hashcode,从而放在了不同的位置。而实际上A和B应该是放在同一位置。

在查找操作中

A已作为key放入HashMap中,通过B作为key来查找A中的值,查找时,先比较hashcode是否相等,如果相等,再比较对象是否相等。
但是这里,因为没有重写hashcode方法,自动调用原生的Object的hashcode,这样就使得A和B产生不同的hashcode,从而不会进行下一步的equals比较,通过B就找不到A。

查找示例代码如下:

import java.util.HashMap;

public class HashTest
{
	private String s;

	private int x;

	public String getS()
	{
		return s;
	}

	public void setS(String s)
	{
		this.s = s;
	}

	public int getX()
	{
		return x;
	}

	public void setX(int x)
	{
		this.x = x;
	}

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

		if ((obj == null) || (obj.getClass() != this.getClass()))
			return false;

		HashTest h = (HashTest) obj;
		if (h.s.equals(this.s) && h.x == this.x)
			return true;
		else
			return false;
	}

	public static void main(String[] args)
	{
		String s = "1";
		HashTest A = new HashTest();
		A.setS(s);
		A.setX(1);

		HashTest B = new HashTest();
		B.setS(s);
		B.setX(1);

		HashMap<HashTest, String> map = new HashMap<HashTest, String>();

		map.put(A, "插入");

		//System.out.println(A.equals(B));
		//System.out.println(A.hashCode());
		//System.out.println(B.hashCode());
		//System.out.println(map.get(A));
		System.out.println(map.get(B));
	}

}

结果如下:

在这里插入图片描述

重写hashcode:

package test;

import java.util.HashMap;

public class HashTest
{
	private String s;

	private int x;

	public String getS()
	{
		return s;
	}

	public void setS(String s)
	{
		this.s = s;
	}

	public int getX()
	{
		return x;
	}

	public void setX(int x)
	{
		this.x = x;
	}

	public boolean equals(Object obj)//注意不可以更改方法名,以及方法的参数
	{
		if (this == obj)
			return true;

		if ((obj == null) || (obj.getClass() != this.getClass()))
			return false;

		HashTest h = (HashTest) obj;
		if (h.s.equals(this.s) && h.x == this.x)
			return true;
		else
			return false;
	}

	public int hashCode()//注意不可以更改方法名,这里的“c”要大写,以及方法的参数,
	{
		int hash = 7;
		hash = 31 * hash + x;
		hash = 31 * hash + s.hashCode();
		return hash;
	}

	public static void main(String[] args)
	{
		String s = "1";
		HashTest A = new HashTest();
		A.setS(s);
		A.setX(1);

		HashTest B = new HashTest();
		B.setS(s);
		B.setX(1);

		HashMap<HashTest, String> map = new HashMap<HashTest, String>();

		map.put(A, "插入");

		//System.out.println(A.equals(B));
		//System.out.println(A.hashCode());
		//System.out.println(B.hashCode());
		//System.out.println(map.get(A));
		System.out.println(map.get(B));
	}

}

结果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值