关于地图中的碰撞
Posted
技术标签:
【中文标题】关于地图中的碰撞【英文标题】:Regarding collision in Map 【发布时间】:2012-08-02 14:12:57 【问题描述】:我正在浏览HashMap并阅读以下分析..
HashMap 实例有两个影响其性能的参数:初始容量和负载因子。
容量是哈希表中的桶数,初始容量就是哈希表创建时的容量。
负载因子衡量哈希表在其容量自动增加之前允许达到的程度。
当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表被重新哈希(即内部数据结构被重建),使得哈希表大约有两倍桶的数量。
默认初始容量为16,默认负载系数为0.75。您可以在地图的构造函数中提供其他值。
现在假设我有一张地图..
HashMap map=new HashMap();//HashMap key random order.
System.out.println("Amit".hashCode());
map.put("Amit","Java");
map.put("mAit","J2EE");
map.put("Saral","J2rrrEE");
我希望发生碰撞,请告知碰撞将如何发生..!!
【问题讨论】:
对不起,我不明白这个,“请告知碰撞是如何发生的” - 为什么你需要一定发生碰撞? “我希望发生碰撞”。为什么?这正是你应该尝试避免。 【参考方案1】:我相信确切的 hashmap 行为取决于实现。只要看看你的类库正在做散列并构造一个冲突。这很简单。
如果您希望在任意对象而不是字符串上发生碰撞,这要容易得多。只需使用始终为 returns 0
的自定义 hashCode()
创建一个类。
【讨论】:
【参考方案2】:当 2 个 key 具有相同的 hash key 时会发生冲突。 我没有计算你的键散列键,但我不认为它们具有相同的散列键,因此如果它们没有相同的散列键,则不会发生冲突。 如果您将与键相同的字符串放在一起,则会发生冲突
【讨论】:
【参考方案3】:如果您希望发生真正的冲突,那么最好编写您自己的自定义哈希码。比如说,如果你想Amit
和mAit
发生冲突,你可以做一件事,只需使用字符的 ascii 值作为哈希码。你会因为不同的键而发生冲突。
【讨论】:
所以我将编写自己的重写 hashcode() 方法,并为所有人返回相同的 hashcode()..!!【参考方案4】:这里的冲突绝对是可能的,并且与哈希表实现无关。 HashMap 在内部工作,通过使用 Object.hashCode 将对象映射到存储桶,然后与 Object.equals 一起使用冲突解决机制(OpenJDK 实现使用分离链)。
为了回答您的问题,String.hashCode 已明确定义为兼容性...
返回此字符串的哈希码。
String
对象的哈希码计算为s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用
int
算术,其中s[i]
是字符串的第i个字符,n
是字符串的长度,^
表示求幂。 (空字符串的哈希值为零。)
或者,在代码中(来自OpenJDK)
public int hashCode()
int h = hash;
if (h == 0 && count > 0)
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++)
h = 31*h + val[off++];
hash = h;
return h;
与任何散列函数一样,冲突是可能的。根据Wikipedia article,它指出例如"FB"
和"Ea"
会产生相同的值。
如果你想要更多,在这里找到具有相同哈希值的冲突应该是一个微不足道的暴力问题。
作为旁注,我想我会指出这与 C 编程语言第二版中的函数非常相似:
#define HASHSIZE 100
unsigned hash(char *s)
unsigned hashval;
for(hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval % HASHSIZE;
【讨论】:
以上是关于关于地图中的碰撞的主要内容,如果未能解决你的问题,请参考以下文章