Java自带容器类的equals和hashCode方法

java中有三大主要的容器类:listsetmap。他们都是interface,在这三大容器类下面分别有AbstractListAbstractSetAbstractMap这三个抽象类去实现他们,他们几乎实现了对应接口中的所有方法(有少数方法没有实现,仍然是abstract的)。其中他们实现的主要的方法就是hashCodeequals方法(toString方法不一定在这些类中实现的,因为他们有的不是直接实现对应接口的,而是通过继承AbstractCollection这个抽象类来实现接口的,toString方法有的是在抽象类中实现的,比如AbstractList就是继承了AbstractCollection的抽象类)。下面我们就来分别的讲解一下他们内部是如何实现hashCodeequals方法的:

 

首先我们需要说明的是他们的实现都是有效的,即他们的实现都能够保证下面的推导成立: a.equals(b) =》 a.hashCode() = b.hashCode()

上面这个是一个充分非必要条件(AbstractSet对于equalshashCode的实现就是一个例子),即a.hashcode() = b.hashcode() =》 a.equals(b)是不对的。

所以有了上面的保证,我们以后就可以放心大胆的使用容器类(凡是继承了AbstractListAbstractSet或者AbstractMap的容器类),而不用担心他们的equalshashcode重新的问题了,而且java的设计者也是不希望我们去重新他们辛辛苦苦设计好的equalshashcode方法的,我们自己贸贸然的重新可能会导致不必要的错误,所谓费力不讨好。比如最常用的就是将一个Set(比如HashSet)作为元素放在另一个Set(比如HashSet)中去,我们就可以直接使用,而不用担心因为hashcodeequals重写的问题造成的逻辑错误。

 

下面我们就来看看java的设计者是如何重新这些方法的:

 

equals()

(a.equals(b)true)

hashCode()

(hashCode()的算法)

AbstractList

1.ab都是List的子类

2.a.size()b.size()相等

3. a中和b中元素必须对应相等,即a中和b中下标相等的元素必须相等(即调用元素本身的equals方法返回true

list中每个元素的hashCode利用特殊的hash算法加起来,详细代码可以参考java源码。

AbstractSet

1. ab都是Set的子类

2. a.size()b.size()相等

3. a中包含b中所有元素,由于Set是不考虑位置顺序的,所以我们不要求位置一样。由于有了第二条的限制,所以这条就保证了ab一定含有相同的元素,当然比较ab中的元素是否相等我们调用的也是元素本身的equals方法,返回true就表示两个元素相等。

将所有非null元素的hash code加起来,当然元素的hash code是通过调用元素的hashCode方法获得的。

AbstractMap

1. ab都是Map的子类

2. a.size()b.size()相等

3. a中包含的mappingb中包含的mapping是相同的,即

a.entrySet().equals(b.entrySet()),具体说来就是a中的key setb中的key set是相等的,并且相同key对应的值也是相等的。值的相等都是通过equals方法判断的。

Map中所有Entry对象的hash code的和(Entry对象的hash code通过调用他们自己的hashCode方法获得)。而Entry类的定义是Entry<K,V>Map中起到存放键值对的作用,Entry<K, V>hash code的算法是:

return 

(key   == null ? 0 :   key.hashCode()) ^

(value == null ? 0 : value.hashCode());

 

结语:愉快的享受java工程师给我们带来的便利吧。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值