2016-07-27 57 views
-2

我正在检查Collection的contains()方法的代码,无法找到hashcode()的用法。这里是链接contains() method javadoccontains()的Collection框架不使用hashcode,而是使用equals(),为什么?

+0

为什么你会期望散列码被使用?两个不相等的对象可能巧合地具有相同的散列码,但是关于集合论,它们都应该被允许占据相同的集合。 –

+0

为什么不等于? –

+0

由于hashcode和equals方法的一致,我期望使用哈希码。 – user6643247

回答

1

为什么没有对ArrayList或LinkedList实现进行优化?

因为它不一定是优化。

如果hashCode明显比equals便宜,那么只需在equals之前致电hashCode即可进行优化。如果您知道该对象的实现hashCode缓存哈希码值和以前在该对象上称为hashCode,那么它可能第一次调用hashCode更快。但是,如果这类原因是不正确的,那么你很可能会发现:

  • hashCode调用至少贵为equals调用(毕竟,hashCode不能“短路”就像一个良好实现的equals经常可以)和
  • 当哈希码值相等时,您仍然需要拨打equals

分析变得很复杂......但我只想说,在很多情况下(考虑哈希码的所有实现和平等相待,平等与不平等等元件的分布)使用hashCode是一种抗优化。尽管如此,如果您有一个用例可以改进使用hashCode作为优化的东西,那么您可以自由地实现自己的自定义集合类。或者更好的是,优化元素类equalshashCode方法,以便equals自己检查(高速缓存的)散列值。

+0

谢谢你的一个非常引人注目的答案,但如果我有一个非常复杂的等价方法,这是昂贵的。然后我猜hashcode可以是非常有用的。但我猜集合框架违反了hashcode和equals方法之间的协议。 – user6643247

+0

1)如果'equals'很复杂,那么'hashCode'可能也必须复杂......否则你会得到很多散列冲突。 2)*“集合框架违反了hashcode和equals方法之间的协议。”*。事实上,它没有。它根本不使用'hashCode' ...所以合约是没有意义的。 –

+0

同意。谢谢!!! – user6643247

0

散列码只是优化。最终,Collection#containsMap#get调用必须调用equals来检查传递的对象是否真的存在,而不是恰好具有相同散列码的另一个对象。如果您查看HashSetHashMap等特定实施方案,您会发现hashCode()作为优化工具一路使用。

+0

是的。同意哈希集合,但在ArrayList实现中,你不会看到哈希码。 – user6643247

+0

为什么没有对ArrayList或q进行优化 – user6643247

+0

为什么没有对ArrayList或LinkedList实现进行优化? – user6643247

0

ArrayList不需要使用hashCode()方法,因为排序由插入顺序决定。 hashCode()方法用于HashSet中的对象或用作HashMap中的键的对象。

+0

Hashcode是两个引用是否指向同一个对象的猜测,这是通过equals方法确认的。那么为什么hashcode不是用来猜测的......稍后equals可以测试对象的状态。 – user6643247

+0

首先,Hascode不是两个引用是否指向同一个对象的猜测。其次,“测试物体的状态”究竟意味着什么? –

+0

等于测试对象的状态.... Hashcode是猜测...您为某个计算附带的对象获取整数值。相同的整数也可以与其他对象一起使用。所以它是一个猜测,参考可以指向同一个对象。 – user6643247