2017-03-14 5 views
0

Javaで単純な整数文字列のキー値のHashMap実装を記述しました。テストしようとすると、私はいくつかのテストコードを書いて、0〜4の値の間(毎回5000のサンプルから)テストが失敗しているのを見ました。そこで、私はHashMapをJavaのデフォルト実装に切り替え、私のテストが明らかに正しい実装に失敗していることに気付きました。だから、私は過去のカップルの時間のために私のテストが失敗している理由を把握しようとしていた。私が紛失しているものはありますか?Java HashMap実装のテストでエラーが発生しました:値の〜99%のみで動作します

は、ここで(まあ、明らかに...そこにある)私のコードです:

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 
+0

私が代わりに乱数のユニークなk値に等しいキーを設定するgetKeys()関数を変更した場合、それは問題を修正することを気づきました。 HashMapsは一意のキーを持つ必要があるため、乱数が前の数に等しくなるわずかなチャンスでテストが完全に失敗します。私は将来誰かがそれを必要とするならば、私はこの投稿を残すだろうと思う。 – David

+0

あなたが見てきたように、キーが重複する可能性はわずかですが、直観に反して見えるかもしれません。これは[誕生日の問題](https://en.wikipedia.org/wiki/Birthday_problem)として知られています。 – shmosel

答えて

0

あなたのキーに重複が(時には)含まれています。これは戻り値map.put(...)を評価することで確認できます。キーがマップに存在しない場合はnullを返します。指定されたキーを持つマップ内のエントリが既に存在する場合、そのエントリの値を返します。

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++){ 
     String previousValue = map.put(keys[i],studentNames[i]); 
     if (previousValue != null) { 
      System.out.println(keys[i] + " is a duplicate key"); 
     } 
    } 
} 
関連する問題