Object对象的通用方法-equals、hashCode



覆盖equals时需要遵守的通用约定
    

在覆盖equals方法的时候,你必须要遵守它的通用约定。下面是约定的内容,来自Object的规范[JavaSE6]

  • 自反性对于任何非null的引用值xx.equals(x)必须返回true
  • 对称性对于任何非null的引用值xy,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true
  • 传递性。对于任何非null的引用值xyz,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true
  • 一致性。对于任何非null的引用值xy,只要equals的比较操作在对象中所用的信息没有被修改,多次调用该x.equals(y)就会一直地返回true,或者一致地返回false
  • 对于任何非null的引用值xx.equals(null)必须返回false


结合以上要求,得出了以下实现高质量equals方法的诀窍:
1.
使用==符号检查参数是否为这个对象的引用
2.
使用instanceof操作符检查参数是否为正确的类型如果不是,则返回false。一般来说,所谓正确的类型是指equals方法所在的那个类。
3.
把参数转换成正确的类型。因为转换之前进行过instanceof测试,所以确保会成功。
4.
对于该类中的每个关键域,检查参数中的域是否与该对象中对应的域相匹配。如果这些测试全部成功,则返回true;否则返回false
5.
当编写完成了equals方法之后,检查对称性传递性一致性

/**
 *@Function: Effective Java 8,9 Object通用方法
 *@Date: 2014-3-18
 */
public class EqualsTest {
	public static void main(String[] args) {
		//通过覆盖equals方法实现特有的"逻辑相等"行为
		System.out.println(new Phone(222,333).equals(new Phone(222,333)));
		//未覆盖hashCode导致获取不到想要的结果
		Map
    
    
     
      map=new HashMap
     
     
      
      ();
		map.put(new Phone(222, 333), "April");
		System.out.println(map.get(new Phone(222,333)));
	}
}
//Effective Java 8,9 Object通用方法
final class Phone {
	private final short num1;
	private final short num2;
	public Phone(int num1,int num2){
		this.num1=(short) num1;
		this.num2=(short) num2;
	}
	/**
	 *@Function: 重写equals以实现特有的"逻辑相等"
	 *	 注:instanceof前的参数为null会直接返回false,所以没必要显式判断null
	 */
	@Override
	public boolean equals(Object o) {
		if(this==o){
			return true;
		}
		if(!(o instanceof Phone)){
			return false;
		}
		Phone p=(Phone)o;
		return p.num1==num1&&p.num2==num2;
	}
	/**
	 *@Function: 覆盖equals时总要覆盖hashCode
	 *否则无法结合所有基于散列的集合一起工作(Hashtable,HashMap,HashSet..)
	 */
	@Override
	public int hashCode() {
		int result=hashCode;
		if(result==0){
		    result=17;
			result=31*result+num1;
			result=31*result+num2;
		}
		hashCode=result;
		return result;
	}
	int hashCode=0;
}

     
     
    
    


覆盖equals时总要覆盖hashCode
    
一个很常见的错误根源在于没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMapHashSetHashtable
覆盖hashCode约定:
  • 在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致
  • 如果两个对象根据equals()方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果
  • 如果两个对象根据equals()方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生相同的整数结果。但是程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能

hashCode的性能优化


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值