equals与hashcode

默认的equal实现:
Object类里定义的equal只是引用的判断,如果二个实例的引用不一样,就认为逻辑上也不一样。
equal定制实现:
但是实际存在二个实例不一样,但是逻辑上是一样的。比如一些值对象的类Date,还比如oauth2里面取回的用户,只要这些用户对象的uid是一样的就认为逻辑相等。
关键词:逻辑相同

equal使用getClass:不使用instanceOf 而使用getClass比较type是因为instanceOf会破坏对等性但是getClass的缺点是只能相同的类比较

The contract of equals mentions that it must be symmetric. This means that a.equals(b) if b.equals(a).
That's the reason why instanceof is usually not used in equals (unless the class is final). Indeed, if some subclass of Book (ComicsBook for example) overrides equals to test that the other object is also an instance of ComicsBook, you'll be in a situation where a Book instance is equal to a ComicsBook instance, but a ComicsBook instance is not equal to a Book instance.
You should thus (except when the class is final or in some other rare cases) rather compare the classes of the two objects:
if (this.getClass() != o.getClass()) {
    return false;
}
BTW, that's what Eclipse does when it generates hashCode and equals methods.



默认的hashcode实现:
Object类里定义hashcode为每个实例返回的值都不一样(public native hashcode();)hashcode 是一个外部调用,为了保证不一样,很可能由实例的地址生成。
hashcode定制实现:
随着equal的定制实现而实现。如果存在二个实例逻辑相等的场景而重写了equal方法,那么hashcode也应该使用equal中用到的属性重写。保证逻辑上相等的对象,hashcode也相等。

注意,规范并没有规定不同的实例有不同的hashcode. 所以不同的实例是可以有相同的hashcode。比如在hashmap,hashset的get/add的实现中,可能key的hashcode与桶里面的某个元素的hashcode相等,所以,并不能由hashcode就判定桶里一定包含了这个key,而应该进一步判断equal。逻辑上不相等的对象最好拥有不相等的hashcode(规范上可以相等,但是考虑到散列的性能,应该尽量不相等)

利用hashcode和equals判断
如果有某个需求要求判断某个字符串是否包含黑词, 可以将这些黑词放入到HashSet里,将字符串利用黑词集合的最大长度与最小长度进行切分. 遍历切词集合,使用黑词集中contains当前切词,命中黑词的时间复杂度=常量来判断是否有黑词.这比使用indexof遍历黑词效率高很多.

原文地址:https://www.cnblogs.com/highriver/p/2073946.html