在 Java 6 中,我的理解是,您可以在创建 TreeSet 时为它提供一个 Comparator 以覆盖集合中对象的“自然顺序”。
你有什么想法为什么 Java 不支持提供覆盖集合中对象的“自然散列”的“Hasher”?
编辑:在未来设计 API 时,从您那里获得输入可能会对我有所帮助。
谢谢。
一个对象对于类中的方法Hasher
来说是多余的。hashCode()
Object
如果你想影响散列的性质,你应该覆盖hashCode()
定义的方法Object
。一定要覆盖equals(Object)
,因为这两个应该总是一起去。
一个HashSet
或其他类似的数据结构将使用 objectshashCode()
方法获取哈希值以确定 bin 存储。然后它将equals()
用于将该对象与同一箱中的其他对象进行比较以确定相等性。
生成的哈希码对于该特定类别的对象必须是唯一的。这可以简单地通过重写hashCode()
方法来确保,并且不需要在实现之间进行更改。一个Hasher
对象只会混淆并且没有其他用途。我想不出一个用例需要多个哈希码来存储在不同的数据结构中。
以下是几个可能的原因:
简单- 大多数人不需要多个哈希函数,因此为了保持 API 简单,依赖单个 Object.hashCode() 方法是有意义的
性能- 至少在标准库中,HashSets 和 HashMaps 等需要进行大量优化,因为它们被广泛使用。调用单独的“哈希器”的开销是没有意义的,无论开销多么小。
私有字段- hashCode() 可能依赖私有字段的问题,可能难以为某些对象创建外部“哈希”。
确实如此!查看Object.hashCode方法。
再次阅读您的问题后,我可能已经过火了。我现在看到您说“覆盖”自然哈希。通常我们在对象级别覆盖哈希值并放弃使用覆盖哈希器。
哈希意味着比比较器更通用。也就是说,散列应该几乎总是创建统一的不信任值,几乎没有冲突的机会。使用它们的容器应该很少需要专门的哈希器。
您可以通过包装一个以您的方式实现哈希码的对象来更改对象的哈希码。假设是您可能希望对象以多种方式排序,但没有多种散列策略。
cf Trove4j 支持其 HashMap 的散列策略,虽然我经常使用这个库,但我只在记得之后才使用自定义散列策略。