当我使用HashMap
获取left_table和right_table之间的公共密钥时(我也在测试Bloom Filter
算法与HashMap
进行比较,所以我添加了标记{{1要引起注意,Bloom Filter
可能有这个问题),我声明了两个HashMap
,当我把right_table中的键放到HashMap hm1 and hm2
(默认值为1)时,键总是发生碰撞。我意识到密钥的哈希值可能是相同的,但为什么它总是出现在同一个地方。当我重新安排hm2
和hm1
的声明时,碰撞仍然存在!
我测试hm2
总是等于n是正确的,它可以存储超过hm1.size
。 2000000 uuids
中的HashMap
工具是否可靠?
Java
上一代码的输出是:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.UUID;
public class HashMapBugTest {
public static void main(String[] argv) {
int n = 100;
int real = 10;
List<String> Uuids_in_left_table = new ArrayList<String>();
// init left table
Long startInsertTime1 = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
String Uuid = UUID.randomUUID().toString();
Uuids_in_left_table.add(Uuid);
}
Long endInsertTime1 = System.currentTimeMillis();
System.out.println("The length of Uuids_in_left_table is:" + Uuids_in_left_table.size());
System.out.println("The time use for insert the uuid into the left table used " + (endInsertTime1 - startInsertTime1) + "ms.");
// init right table
List<String> Uuids_in_right_table = new ArrayList<String>();
Random r = new Random(n);
Long startInsertTime2 = System.currentTimeMillis();
for (int i = 0; i < n - real; i++) {
String Uuid = UUID.randomUUID().toString();
Uuids_in_right_table.add(Uuid);
}
for (int i = 0; i < real; i++) {
String Uuid = Uuids_in_left_table.get(r.nextInt(n));
Uuids_in_right_table.add(Uuid);
}
Long endInsertTime2 = System.currentTimeMillis();
System.out.println("The length of Uuids_in_left_table is: " + Uuids_in_left_table.size());
System.out.println("The time use for insert the uuid into the right table used " + (endInsertTime2 - startInsertTime2) + "ms.");
// build hashmap
HashMap<String, Object> hm2 = new HashMap<String, Object>();
HashMap<String, Object> hm1 = new HashMap<String, Object>();
for (int i = 0; i < n; i++) {
int ind = hm2.size();
if (ind == 97)
System.out.println(hm2.containsKey(Uuids_in_right_table.get(ind)));
hm2.put(Uuids_in_right_table.get(i), 1);
if (ind == hm2.size())
System.out.println("a"+i+"---"+Uuids_in_right_table.get(i));
}
for (int i = 0; i < n; i++) {
hm1.put(Uuids_in_left_table.get(i), 1);
}
int cnt = 0;
System.out.println("length of hm1 is:" + hm1.size());
System.out.println("length of hm2 is:" + hm2.size());
Long startHashMapTime = System.currentTimeMillis();
for (String str:hm1.keySet()) {
if (hm2.containsKey(str))
cnt += 1;
}
Long endHashMapTime = System.currentTimeMillis();
System.out.println("The time used for check the uuid common in the left table and right table used " + (endHashMapTime - startHashMapTime) + "ms.");
System.out.println("The number of common uuid is:" + cnt);
}
}
答案 0 :(得分:0)
你的问题如此可重复的原因是这一行:
Random r = new Random(n);
它没有按照你的想法做到。
它的作用:它创建一个带有初始种子n
的随机生成器。
由于n
在你的程序中总是10,这意味着你总是得到相同的随机数序列。
始终将从左侧列表中挑选的10个uuid完全导入右侧列表,并且索引88使用两次。
修正:
Random r = new Random();
这将创建一个随机生成器,其初始种子基于当前时间(以毫秒为单位),因此每次运行该程序时,您很可能会得到10个不同的10个数字列表。
您的代码未突出显示HashMap
中的任何问题。如果将同一个键(左侧列表中索引88的uuid)插入hm2
两次,则第二次插入时将覆盖第一次插入时。而不是你想象的100个元素,它只包含99个元素。