为什么我们可以为TreeSet提供Comparator而不是Hasher到HashSet?

时间:2010-12-14 14:52:25

标签: java hashset treeset

在Java 6中,我的理解是你可以在创建TreeSet时为它提供一个Comparator,以覆盖集合中对象的“自然顺序”。

你有没有想过为什么Java不支持提供一个“Hasher”来覆盖集合中对象的“自然散列”?

编辑: 在将来设计API时,获取您的意见可能对我有帮助。

感谢。

5 个答案:

答案 0 :(得分:2)

Hasher类中的hashCode()方法,Object对象将是多余的。

如果要影响散列的性质,则应覆盖hashCode()上定义的Object方法。请务必覆盖equals(Object),因为这两者应该总是一起使用。

HashSet或其他类似的数据结构将使用对象hashCode()方法来获取哈希值以确定bin存储。然后,它将使用equals()将该对象与同一个bin中的其他对象进行比较,以确定相等性。

生成的哈希码需要对该特定对象类唯一。这可以通过覆盖hashCode()方法来确保,而不需要从实现更改为实现。 Hasher对象只会混淆并且不会用于其他目的。我想不出单个用例,在不同的数据结构中存储需要多个哈希码。

答案 1 :(得分:2)

以下是几个可能的原因:

  • 简单 - 大多数人不需要多个哈希函数,因此为了保持API简单,依赖单个Object.hashCode()方法是有意义的

    < / LI>
  • 效果 - 至少在标准库中, HashSets和HashMaps等需要 因为它们非常优化 如此广泛使用。这没有意义 有调用的开销 单独的“哈希”,无论多么小 开销可能是。

  • 私有字段 - 存在问题 hashCode()可能依赖私有 字段,可能很难 为某些人创造外部“哈希” 对象

答案 2 :(得分:1)

确实如此!查看Object.hashCode方法。

再次阅读你的问题后,我可能已经开枪了。我现在看到你说“覆盖”自然的hshing。通常我们会覆盖对象级别的哈希值,并放弃使用覆盖的哈希。

哈希比对手更具普遍性。也就是说,哈希几乎总是会产生统一的不信任值,几乎没有碰撞的可能性。使用它们的容器应该很少需要专门的垫圈。

答案 3 :(得分:1)

答案 4 :(得分:0)

您可以通过包装一个对象来更改对象的哈希码,该对象以您的方式填充哈希码。假设您可能希望对象按几种方式排序,但没有多个散列策略。

c.f。 Trove4j支持其HashMap的散列策略,虽然我经常使用这个库,但是一旦我记得,我只使用了自定义散列策略。