Java equals和hashCode

equals()和hashCode()方法是Java类库大多都继承和实现的方法。前者用于比较对象之间内容相等性,后者用于对象在HashMap中提供有效的索引。那么,在软件设计中该如何override这两个方法呢?

对象相等性

对象在创建后有两个标识equals和hashCode。通常情况下,如果重写了其中一个方法,也必须重写另一个方法。即要求equals相等的对象,要求其hashCode值也相等。

如果在Class中不 Override equals()和hashCode()。如果从未在HashMap或其它基于散列的集合中使用该类作为关键字的话,什么也不会发生。但是,如果在HashMap中使用该类实体对象作为关键字,我们将不能够可靠地检索到相关值,除非我们在get()调用中使用与put()调用中极其类似的类实例,这种方法极不方便而且出错的概率也非常大。

其实,程序也可根据equals()方法识别具体的类,但是由于equals()方法在计算方面非常耗时。Java平台设计人员为满足应用程序中基于散列的集合类(Collection Class)--如Hashtable,HashMap 和HashSet,创造出hashCode并结合使用基于散列的集合,提高存储和检索的效率。

重新equals和hashCode原则

在重新equals()和hashCode()原则有:

  • Symmetry:两个引用, a和b a.equals(b)则有b.equals(a)。
  • Reflexivity:所有非空引用,a.equals(a)。
  • Transitivity:如果a.equals(b) 且b.equals(c), 则a.equals(c。
  • Consistency with hashCode() :两个相等的对象必须有相同的hashCode()值。
  • Non nullity:非空性,任何飞空的对象a,a.equals(null)返回为false。

编写有效的equals和hashCode方法

如何编写有效的equals和hashCode方法是类设计的关键。equals方法相对简单,这里不做介绍。不理想的hashCode方法会导致不相等的类具有相同的hashCode值,这将给散列集合类查找带来错误的结果。比如类:

class Example{
		int a;
		int b;
}

糟糕的hashCode:
public int hashCode() {
			return a + b;
		}
如何才能设计良好的hashCode实现呢?良好的hashCode实现即要保存某一个变量的特性,还要保存其他变量的特性。
class A {
    final B someNonNullField;
    C someOtherField;
    int someNonStateField;
  }
好的hashCode实现,保存了3个属性值得特性:
public int hashCode() { 
    int hash = 1;
    hash = hash * 31 + someNonNullField.hashCode();
    hash = hash * 31 
                + (someOtherField == null ? 0 : someOtherField.hashCode());
    return hash;
  }

总结

通过重写equals() 和 hashCode(),提升类在散列集合应用中的可行性。但是,当对象状态发生变化导致对象散列值发生变化时,有可能取到错误的结果




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值