如果我创建新的Map
:
Map<Integer,String> map = new HashMap<Integer,String>();
然后我多次拨打map.put()
,每个都有一个唯一的密钥,比如一百万次,是否会发生冲突,或者如果密钥是唯一的,那么java的哈希算法可以保证不会发生冲突?
答案 0 :(得分:3)
如果密钥是唯一的,则散列不保证不会发生冲突。实际上,唯一需要的是相等的对象具有相同的哈希码。碰撞的数量决定了检索的有效性(更少的碰撞,更接近O(1),更多的碰撞,更接近O(n))。
对象的哈希码将取决于它的类型。例如,字符串的默认哈希码是
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
这必然会将字符串的复杂性简化为单个数字 - 绝对有可能使用两个不同的字符串来达到相同的哈希码,尽管它很少见。
如果两件事情都是哈希,那么hashmap使用.equals
来确定特定的密钥是否匹配。这就是为什么同时重写hashCode()
和equals()
以及确保相同的内容具有相同的哈希码的重要性。
答案 1 :(得分:1)
Hashtable的工作方式如下:
使用初始容量(或桶数)创建散列映射
每次向它添加一个对象时,java都会调用该键的哈希函数,一个数字,然后将其模数为哈希表的当前大小
对象存储在存储桶中,其结果来自步骤2.
因此,即使您拥有唯一的密钥,它们仍然会发生冲突,除非您的密钥范围与密钥的哈希范围一样多。
答案 2 :(得分:1)
您需要了解两件事:
即使有碰撞,也不会引起问题,因为对于每个桶,都有一个列表。如果你要放入一个已经有值的桶,它只会附加在列表中。检索时,它将首先找出要查找的存储桶,然后从存储桶中查看列表中的每个值并找出等于的值(通过调用equals()
)
如果你在Hashmap中投入数百万的价值,你可能会想,那么地图中的每个链表都会包含数千个值。然后我们总是进行大线性搜索,这将很慢。然后你需要知道,只要条目数大于某个阈值(看看容量和Javadoc中的loadFactor),就会调整Java的HashMap的大小。使用正确实现的哈希码,每个桶中的条目数量将会很小。