为什么我们可以为 TreeSet 提供 Comparator,但不能为 HashSet 提供类似 Hasher 的东西?
在 Java 6 中,我的理解是,您可以在创建 TreeSet 时向 TreeSet 提供 Comparator,以覆盖集合中对象的“自然顺序”。
您是否有任何想法为什么 Java 不支持提供覆盖集合中对象的“自然哈希”的“哈希器”?
编辑: 从您那里获取意见可能会对我将来设计 API 时有所帮助。
谢谢。
In Java 6, my understanding is that you can supply a Comparator to a TreeSet when creating it to override the "natural ordering" of the objects in the set.
Do you have any thoughts why Java doesn't support supplying a "Hasher" that overrides the "natural hashing" of objects in the set as well?
EDIT:
Getting input from you might help me when designing APIs in the future.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
以下是几个可能的原因:
简单 - 大多数人不需要多个哈希函数,因此为了保持 API 简单,依赖单个 Object.hashCode() 方法是有意义的
性能 - 至少在标准库中,
HashSets 和 HashMaps 等需要
相当程度的优化,因为他们是
如此广泛使用。这没有意义
有调用的开销
单独的“哈希器”,无论多么小
开销可能是。
私有字段 - 存在这样的问题:
hashCode() 可能依赖于 private
领域,可能很难
为某些人创建外部“哈希器”
对象。
Here are several likely reasons:
Simplicity - most people don't need multiple hash functions, so to keep the API simple it makes sense to rely on a single Object.hashCode() approach
Performance - In the standard library at least,
HashSets and HashMaps etc. need to be
pretty heavily optimised as they are
so widely used. It doesn't make sense
to have the overhead of calling a
separate "hasher", however small that
overhead may be.
Private fields - there is the issue that
hashCode() may rely on private
fields, it may be difficult to
create external "hashers" for some
objects.
Hasher
对象对于Object
类中的hashCode()
方法来说是多余的。如果您想实现由于哈希的本质,您应该重写
Object
上定义的hashCode()
方法。请务必覆盖equals(Object)
,因为这两者应该始终结合在一起。HashSet
或其他类似的数据结构将使用对象hashCode()
方法来获取哈希值来确定 bin 存储。然后,它将使用 equals() 将该对象与同一容器中的其他对象进行比较以确定是否相等。生成的哈希码对于该特定对象类来说必须是唯一的。只需重写
hashCode()
方法即可确保这一点,并且不需要在实现之间进行更改。Hasher
对象只会混淆并且没有任何其他目的。我无法想到需要多个哈希码来存储在不同数据结构中的单个用例。A
Hasher
object would be redundant to thehashCode()
method in theObject
class.If you want to effect the nature of the hashing, you should override the
hashCode()
method defined onObject
. Just be sure to overrideequals(Object)
as well, since these two should always go together.A
HashSet
or other similar data structure will use the objectshashCode()
method to get a hash value to determine bin storage. It will then useequals()
to compare that object to other objects in the same bin to determine equality.The hash code generated needs to be unique to that specific class of object. This can be ensured simply by overriding the
hashCode()
method and doesn't need to change from implementation to implementation. AHasher
object would just obfuscate and serve no additional purpose. I couldn't think of a single use case where multiple hash codes would be needed for storage in different data structures.确实如此!查看Object.hashCode 方法。
再次阅读你的问题后,我可能已经抢先了。我现在看到你说“覆盖”自然 hshing。通常我们会在对象级别重写哈希值并放弃使用重写哈希器。
哈希值比比较器更通用。也就是说,哈希值几乎总是会创建统一的不可信值,而几乎不会发生冲突。使用它们的容器很少需要专门的哈希器。
It does! Check out the Object.hashCode method.
After reading your question again I might have jumped the gun. I now see that you said "override" the natural hshing. Usually we override the hash value at the object level and forgo the use of a overriding Hasher.
Hashes are meant to be more universal that comparators. That is, hashes should almost always create uniform distrusted values with little chance of collision. The container in which they are used should rarely need a specialized hasher.
已经有人询问过。
It has already been asked.
您可以通过包装一个以您的方式实现哈希代码的对象来更改对象的哈希代码。假设您可能希望对对象进行多种排序,但不希望有多种哈希策略。
cf Trove4j 支持其 HashMap 的哈希策略,虽然我经常使用这个库,但我只在我记得的时候使用过自定义哈希策略。
You can change the hash code of an object by wrapping in an Object which inplements hash code your way. The assumption is that you may want to have a objects sorted a numebr of ways, but not have multiple hashing strategies.
c.f. Trove4j supports hashing strategies for its HashMap and while I use this library often I have only used a custom hashing strategy once I can remember.