Java hashCode() 与 equals () 的基本用法

Java hashCode() 与 equals ()


hashCode() 与 equals() 是定义在 Object 类中的方法, Java 中所有类都默认继承自 Object 类。但是当你声明一个类的时候并不用这样写:
public class Employee extends Object

如果没有明确的指出超类,就默认超类为 Object 类。因此,任何类都能调用继承自 Object 的 hashCode() 与 equals() 方法

hashCode() 与 equals() 的用法

equals()方法

equals() 用于判断两个对象是否相等,Object 类中的 equals() 比较两个类的引用是否相等,如果引用相等,就返回true,否则返回 false。

有些时候,默认的 equals() 方法并不适用,例如,我们根据员工的ID来判断两个员工对象是否相等。但是默认的 equals() 方法只是比较两个对象的引用。 所以我们需要在 Employee 类中重写 equals() 方法,让 equals() 方法比较两个员工的 ID 。

public class Employee {

	private String name;
	private int ID;

   //Getter-Setter

	@Override
	public boolean equals(Object otherObject) {
		Employee other = (Employee) otherObject;

		// 比较它们的ID是否相等
		return this.getID() == other.getID();

	}
}

这样的改动并不完美,我们加入一些优化措施

	@Override
	public boolean equals(Object otherObject) {
		Employee other = (Employee) otherObject;
		
		//== 比较连个对象是否指向用一个引用
		if(this==otherObject)return true;
		
		//检测另一个类是否为null
		if(otherObject==null) return false;
		
		//检测Class是否相等
		if(this.getClass()!=otherObject.getClass()) 
			return false;
		

		// 比较它们的ID是否相等
		return this.getID() == other.getID();

	}

实现equals时有个常见的错误:
这个方法接收参数的类型是Employee,因此,它并没有覆盖Object类中的equals方法,这个方法与Object类中的equals() 毫无关系。

//...

public boolean equals(Employee otherObject)

//...

为了避免这种低级错误,建议用 @Override标记覆盖超类的方法。

@Override
public boolean equals(Object otherObject)

重写equals()方法需要遵循的原则:

  • 若x.equals(y)返回true 则y.equals(x)应当返回true。
  • x.equals(y)返回true 且 y.equals(z)返回true,则x.equals(y)应当返回true。
  • 对于任意不为null 的对象x, x.equals(null)应当返回false。

hashCode() 方法

散列码(hashcode) 是由对象导出的一个整型值。默认的 hashCode() 方法根据对象在内存中的地址,计算对象的散列码。一般来说,如果a 和 b 是两个不同的对象,a.hashCode() 与b.hashCode() 肯定不同。

如果重写了equals方法,请一定不要忘了重写 hashCode() 方法,java 官方文档中是这样写的:

如果两个对象用equal() 方法比较时相等,那么它们的 hashCode() 方法应该返回同样的值 。

我们按照要求,在 Employee 中重写 hashcode 方法

@Override
		public int hashCode()
		{
		    final int PRIME = 1;
		    int result = 1 + getId();
		    return result;
		}

注意hashCode 的实现不唯一,只要能实现上面的要求就行

如果忘记重写 hashCode() ,可能会带来难以预料的后果,比如:


public static void main(String[] args) {

		Employee e1=new Employee();
		Employee e2=new Employee();
		e1.setId(123);
		e2.setId(123);
		//打印结果为true
		System.out.println(e1.equals(e2));
		
		
		Set<Employee> hashset = new HashSet<Employee>();
		hashset.add(e1);
		hashset.add(e2);
		//打印结果为2
        System.out.println(hashset.size());
	}

在例子中,e1和e2的id 都被设置为123,它们是两个相等的对象,因为上一步我们已经重写了 equals() 方法,该方法比较两个对象的id是否相等,相等则返回true,否则返回false。

但是当我们尝试将e1,和e2放入set中的时候,问题出现了,我们知道set中不能放置重复的元素,但是在这里 set 中却能够同时放入e1和e2,这显然不符合我们的逻辑。

至此,hashCode() 与 equals () 的基本用法介绍完毕。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值