许多书籍和教程都指出,散列表的大小必须是在所有桶中均匀分配密钥的首要条件。但是Java的HashMap
总是使用2的幂的大小。它不应该使用素数?有什么更好的,作为散列表大小的“主要”或“两个幂”?Java:作为HashMap大小的“主要”编号或“两个幂”?
回答
使用2的幂有效地掩盖了哈希码的最高位。因此,在这种情况下,质量很差的散列函数可能表现得尤为糟糕。
Java的HashMap
减轻这种由不信任对象的hashCode()
实施和applying a second level of hashing to its result:
适用的补充哈希函数在给定的hashCode,其抵御质量差的散列函数。这是至关重要的,因为HashMap使用幂的二长度哈希表,否则碰到hashCodes的冲突,这些冲突在较低位中不相同。
如果你有一个好的哈希函数,或做类似于HashMap
做一些事情,这不要紧,你是否使用质数等作为表的大小。
另一方面,如果哈希函数是未知的或质量较差,那么使用素数将是更安全的选择。但是,它会使动态大小的表更易于实现,因为突然之间,您需要能够生成素数,而不是仅将大小乘以常数因子。
出于好奇:为什么? (或者你有参考/链接解释这一点)? – 2013-03-15 16:24:39
+1更新 – 2013-03-15 16:31:17
您确定表格大小无关紧要吗?为了减少冲突的数量,是不是一个好的散列函数将数据分散到整个表中的要点?但是,如果表格非常小,那么无论哈希函数如何,碰撞都会增加。我错过了什么吗? – pamphlet 2013-03-15 16:32:01
标准的HashMap实现有一个hash
方法,它可以重新设置对象的哈希码以避免陷阱。 the hash()
method之前注释如下:
/**
* Retrieve object hash code and applies a supplemental hash function to the
* result hash, which defends against poor quality hash functions. This is
* critical because HashMap uses power-of-two length hash tables, that
* otherwise encounter collisions for hashCodes that do not differ
* in lower bits. Note: Null keys always map to hash 0, thus index 0.
*/
从幂的两种尺寸可以只用位屏蔽,比这将被另外要求整数除法更快来计算的视性能/计算时间点。
要想知道哪个更好,哪个更好,哪个更好,只需要对它进行基准测试。很多年前,当编写一个汇编程序,其性能强烈依赖于符号talbe查找时,我使用大量生成的标识符对其进行了测试。即使有一个天真的映射,我发现如预期的那样,两次幂分布的分布均匀性和链长比类似大小的素数桶更少。由于通过位掩码选择存储区的速度,它仍然跑得更快。
我强烈怀疑java.util开发人员不会使用额外的哈希和两次幂的方法,而无需使用质数的存储桶进行基准测试。在设计散列数据结构时,这是一件非常明显的事情。
由于这个原因,我确定重新哈希和二次幂的大小会为典型的Java哈希映射提供比质数的桶更好的性能。
如果您使用quadratic probing进行冲突解决,您可能应该使用素数大小的散列表。如果你有一个主要大小的表格,二次探测将达到一半的条目,如果它不是素数的话,则会减少。所以即使你的哈希表少于半满,你也可能找不到合适的地方存储你的条目。由于Java哈希映射不使用二次探测,所以不需要使用素数作为大小。
- 1. Java hashmap最大大小为5770?
- 2. Java HashMap/Hashtable和编号
- 3. 为什么HashMap要求初始容量是2的幂次?
- 4. 如何从最小编号到最大编号 - Java?
- 5. 为什么Java 6编译的类的大小比Java 5大?
- 6. 限制Java中的HashMap的最大大小
- 7. 使用引号作为键的Bash hashmap
- 8. HashMap put或putAll? - Java
- 9. 为什么使用2的幂作为散列大小使散列表比使用素数要差得多?
- 10. 为什么磁盘块的大小应该是2的幂?
- 11. 维护列表大小一个HashMap
- 12. Java HashMap的大小()能否与其实际条目的大小不同步?
- 13. Java - 管理线程池的大小(主要增加)
- 14. 页表条目大小 - 为什么是2的幂次?
- 15. 并发HashMap:检查大小
- 16. 困惑hashmap#调整大小
- 17. Java的两个班,我需要与主要方法帮助
- 18. java中的Array和Hashmap之间的主要区别是什么?
- 19. 为什么要减小Java JVM线程堆栈的大小?
- 20. 编辑符号位置或大小不总是准确的?
- 21. 大屏幕或hdpi的主屏幕小部件大小?
- 22. 两台设备如何共享相同的主要次要设备编号?
- 23. 存储多个尺寸的图像或只存储主要和调整大小?
- 24. 如何为jenkins工作需要两个或多个标签?
- 25. 为什么这个hashmap初始容量试图调整大小?
- 26. 一个大的查询或两个小的JTable?
- 27. 两个主要功能
- 28. 添加一个HashMap作为一个值的HashMap
- 29. 的Java编程的FileDialog集大小
- 30. Java堆大小 - 将工作?
我怀疑他们是否确切地表达了这一点,如果他们确实如此,他们是错的。这只是一种做法。 – EJP 2013-03-16 00:07:58