Java中的重写equal方法时同时重写hashcode方法的必要性

一、前言
在完成实验二的ConcreteEdgesGraph类时,我遇到这样一个问题,在已经重写了equal方法后,判断一个Set中是否包含某个元素时返回错误,在我的预想中本应返回false却返回了true。

package test;

import java.util.HashSet;
import java.util.Set;

public class Main {
	private final Set<Person> vertices = new HashSet<>();
	
	public static void main(String[] args) {
		Main graph = new Main();
		Person p_1 = new Person("a");
		Person p_2 = new Person("a");
		System.out.println(graph.vertices.add(p_1));
		System.out.println(graph.vertices.add(p_2));
	}
	
	public boolean add(Person vertex) {	//添加点,若点已存在则返回false
        //throw new RuntimeException("not implemented");
    	if (vertices.contains(vertex)) {
    		return false;
    	} else {
    		vertices.add(vertex);
    		return true;
    	}
    }
	
}
package test;

public class Person {
	private String name;	//姓名
	public boolean visit = false;	//记录是否已遍历
	public int distance;	//记录距离
	public Person(String name) {
		this.name = name;
	}
	public String nameGetter() {
		return this.name;
	}
	
	@Override public boolean equals(Object obj) {
        if (this == obj) {
            return true;	//地址相等
        }
        if (obj == null) {
            return false;	//非空性:对于任意非空引用x,x.equals(null)应该返回false。
        }
        if (obj instanceof Person) {
        	Person other = (Person) obj;	//需要比较的字段相等,则这两个对象相等
            if(this.name.equals(other.name)) {
                return true;
            }
        }
        return false;
    }
	
	@Override public int hashCode() {
        return name.hashCode();
    }
	
}

这不由引发了我的思考。在涉及容器是否包含某一元素的的判断中,是否是简单地遍历容器中元素并调用equal方法?重写了equal方法后能否保证两个看似等价的元素实际等价?
在搜索资料后,对这一问题我有了大致的了解。

二、hashcode方法
hashCode()方法给对象返回一个hash code值。这个方法被用于hash tables,例如HashMap。
它的性质是:
(1)在一个Java应用的执行期间,如果一个对象提供给equals做比较的信息没有被修改的话,该对象多次调用hashCode()方法,该方法必须始终如一返回同一个integer。
(2)如果两个对象根据equals(Object)方法是相等的,那么调用二者各自的hashCode()方法必须产生同一个integer结果。
(3)并不要求根据equals(java.lang.Object)方法不相等的两个对象,调用二者各自的hashCode()方法必须产生不同的integer结果。然而,程序员应该意识到对于不同的对象产生不同的integer结果,有可能会提高hash table的性能。
在进行前面比较元素是否相同的操作时,实际上是先调用了hashcode方法,若hashcode方法返回相同的值,再调用equal方法,若equal方法返回true,则两个元素相同。

三、修改
我前面出现问题的原因就是没有重写hashcode方法,导致两个equal方法返回true的元素调用hashcode方法返回的值却不同,这样在第一步判断时便会之间产生两个元素不相等的判断结果。因此除了重写equal方法外,也有必要重写hashcode方法。
将我Person类加上hashcode方法的重写。

@Override public int hashCode() {
        return name.hashCode();
    }

这次结果正确。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值