【发布时间】:2018-06-19 11:01:11
【问题描述】:
我有以下场景,正在寻找“最佳”实现:
- 我想将项目存储在
java.util.Collection中以实现接口 - 保证所有物品都有唯一的
hashCode - 我知道要存储的项目的最大数量
n(最大capacity在初始化时已知) -
hashCode在0到n之间 - 顺序不重要,不需要重复(需要
Set-properties) - 项目可以添加,但永远不会被删除
-
contains的性能非常重要(期望:O(1),至少O(log_n))
我的第一个想法是使用new HashSet<item>(n+1, 1.0),但在阅读后发现它对项目的hashCode 应用了一个内部哈希函数,因此即使hashCodes 是独一无二的hachCode <= n。
我的第二个想法是使用原生数组 (new item[n]) 并使用 hashCode 作为索引。这似乎是性能最好的实现,但我的界面需要java.util.Collection,并且该集合将与contains 和add 一起使用,这与第二种方法的好处不兼容。
是我遗漏了什么,还是我必须接受HashSet 的开销和冲突才能获得最佳性能?
【问题讨论】:
-
使用哈希集,除非您真正观察到性能问题,否则不要担心性能。
-
如果您担心哈希冲突,您就不能定义自己的
hashCode()方法吗?而且,鉴于哈希冲突很少见 - 为什么它甚至重要? -
我只会选择 HashSet。它满足您指定的所有要求。没有重复,O(1) 检索。此外,由于它是一个标准的 java 类,因此您将数据操作到不同的结构/顺序等将比您提供自己的自定义实现更容易。
-
如果您事先知道集合中将包含哪些元素,您可以尝试提出一个 hashCode 函数,该函数为每个元素提供唯一的结果;否则,碰撞只是生活中的事实。
-
@vikingsteve @Maurice 请参阅我的问题的第 2 点。我的
item类的hashCode()方法不是问题,但在内部HashSet使用另一种散列算法根据项目的hashCode计算存储桶。这确保了即使hashCodes 实现不佳的对象也可以被有效地存储。它基本上会导致很少的碰撞,但几乎从来没有。
标签: java collections hashset