【发布时间】:2017-03-14 05:13:53
【问题描述】:
我为 Java 中的简单整数字符串键值编写了一个 HashMap 实现。在尝试对其进行测试时,我编写了一些测试代码,并看到每次有 0-4 个值(在 5000 个样本中),测试都失败了。所以我然后将我的 HashMap 切换到 Java 默认实现,并注意到我的测试没有通过明显正确的实现。所以,在过去的几个小时里,我一直被挂断,试图找出我的测试失败的原因。有什么我想念的吗? (嗯,显然有……)
这是我的代码:
package HashMapOther;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.HashMap;
public class StudentStore {
private static SecureRandom random = new SecureRandom();
static HashMap<Integer, String> map;
static String[] studentNames;
static int[] keys;
static int magicNumber =5000; //still fails no matter size
public static void main(String[] args){
long startTime = System.currentTimeMillis();
start();
test();
long endTime = System.currentTimeMillis();
System.out.println("TIME: " + (endTime - startTime) + " ms");
}
public static void start(){
studentNames = getStudents(); //random strings
keys = getKeys(); //random integers
map = new HashMap<Integer, String>(magicNumber, (float) 0.7);
for(int i=0; i< magicNumber; i++){
map.put(keys[i],studentNames[i]);
}
}
public static int[] getKeys(){ //random integers
int[] a = new int[magicNumber];
for(int k=0; k< magicNumber; k++){
a[k] = (int) (Math.random()*10000000+1);
}
return a;
}
public static String[] getStudents(){ //random strings
String[] temp = new String[magicNumber];
for(int i=0; i<magicNumber; i++){
temp[i] = randomString();
}
return temp;
}
public static String randomString(){ //random string
return new BigInteger(130, random).toString(32);
}
public static void test(){ //test code
boolean passed = true;
for(int i=0; i<magicNumber; i++){
if(!studentNames[i].equals(map.get(keys[i]))){
System.out.println("FAILURE: "+studentNames[i] + " " + map.get(keys[i]));
passed = false;
}
}
System.out.println("RESULT: " + passed);
}
}
这是示例输出:
FAILURE: vq0cpihdsr4vfru6126suufvp4 3dq4shra6dps49psehqjuof4ib
FAILURE: lo2t73n1upqk6cmirdpui29ndt r6accv6ja5pkv723c5g0fe0d1q
RESULT: false
TIME: 94 ms
或者,在另一个运行中:
RESULT: true
TIME: 104 ms
还有一个:
FAILURE: c7848b9rejbtguj2d70llotvpu od7r0fjdphvdli6mgonbictg4d
FAILURE: 4ouk2cj9ipoo4hjrco8vd6p7e kt0u925jdn102cjul96thsfhcm
FAILURE: 2spd0u9lp7531hm09rqu8oncvm scrui9hl7tr0aq85at13oekgf7
RESULT: false
TIME: 99 ms
【问题讨论】:
-
我注意到,如果我更改 getKeys() 函数以将键设置为唯一的 k 值而不是随机数,它可以解决问题。由于 HashMaps 必须有唯一的键,随机数与前一个数相等的微小机会足以使测试完全失败。我想如果将来有人需要,我会留下这篇文章。
-
如您所见,重复键的可能性并不小,尽管它可能看起来违反直觉。这被称为birthday problem。
标签: java testing hashmap hashtable