2017-03-10 44 views
1

所以我試圖檢測我的線性方法中的碰撞,這是散列我的哈希映射studentMap的鍵。我有線性探測的基本功能,但是我正在努力檢測一個鍵是否已經存在(因此+ 1)。到目前爲止,這段代碼不起作用 - 它不檢查我的地圖studentMap中的密鑰是否存在。 任何幫助非常感謝!我已經刪除了其他一些散列方法,以減少代碼的大小,因爲它們是不相關的。碰撞分辨率線性探測Java

public class Main { 
    Student student; 
    public static boolean vartrue; 
    HashMap next; 
    public HashMap<String,Student> studentMap; 
    public static void main(String[] args) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException { 
     HashMap<String, String> studentMap = new HashMap<>(16, 0.75f); 
     //et keys and value 
     studentMap.keySet().forEach((key) -> { 
      String value = studentMap.get(key); 
      System.out.println("Key = " + key + ", Value = " + value); 
     }); 
     //adding values to array 
     studentMap.put("16012804", "Jennifer"); 
     studentMap.put("13747732", "Beatrice"); 
     studentMap.put("14056983", "Mavis"); 
     studentMap.put("16013464", "Geoffrey"); 
     studentMap.put("14058392", "Bob"); 
     studentMap.put("15405833", "Bill"); 
     studentMap.put("14058039", "Gertrude"); 
     studentMap.put("13056496", "Dorothy"); 
     //iterating through the array 
     Set set = studentMap.entrySet(); 
     Iterator iterator = set.iterator(); 
     while(iterator.hasNext()) { 
      Map.Entry mapentry = (Map.Entry)iterator.next(); 
      System.out.print("Key is: "+ mapentry.getKey() + " & Value is: "); 
      System.out.println(mapentry.getValue()); 
     } 
     //Get values based on key 
     String var= studentMap.get("16012804"); 
     System.out.println("Value at index 1 is: "+var); 
     // Remove values based on key 
     studentMap.remove("16012804"); 
     System.out.println("Map key and values after removal:"); 
     Set set2 = studentMap.entrySet(); 
     Iterator iterator2 = set2.iterator(); 
     while(iterator2.hasNext()) { 
      Map.Entry mapentry2 = (Map.Entry)iterator2.next(); 
      System.out.print("Key is: "+mapentry2.getKey() + " & Value is: "); 
      System.out.println(mapentry2.getValue()); 
     } 
     Set keyset = studentMap.keySet(); 
     System.out.println("Key set values are:" + keyset); 
     boolean val = studentMap.isEmpty(); 
     System.out.println("Is hash map empty: " + val); 
     //get values 
     Collection<String> values = studentMap.values(); 
     System.out.println("Map values = " + values); 
     //size of table 
     System.out.println("Size of the Hashtable: " + studentMap.size()); 
     //initial capacity 
     System.out.println("Initial Capacity: " + 16); 
     //capacity of map 
     System.out.println("Map capacity: " + mapcapacity(studentMap)); 
     //load factor 
     System.out.println("Load Factor: " + loadFactor(studentMap)); 

     //linear probing 
     System.out.println("..."); 
     System.out.println("Hash Value(\"Jennifer\")="+ linear(studentMap, "16012804")); 
     System.out.println("Hash Value(\"Mavis\")="+ linear(studentMap, "14056983")); 
     System.out.println("Hash Value(\"Geoffrey\")="+ linear(studentMap, "16013464")); 
     System.out.println("Hash Value(\"Bill\")="+ linear(studentMap, "15405833")); 
     System.out.println("Hash Value(\"Gertrude\")="+ linear(studentMap, "14058039")); 
     System.out.println("Hash Value(\"Beatrice\")="+ linear(studentMap, "13747732")); 
     System.out.println("Hash Value(\"Bob\")="+ linear(studentMap, "14058392")); 

     if (vartrue = true) 
      { 
      Map<String, String> map1 = new HashMap<>(mapcapacity(studentMap) * 2); 
      map1.putAll(studentMap); 
      //capacity of the new hash map. (reflection) 
      System.out.println("Map 1 mappings= " + map1); 
      Field tableField = HashMap.class.getDeclaredField("table"); 
      tableField.setAccessible(true); 
      Object[] table = (Object[]) tableField.get(map1); 
      System.out.println("Size of Map 1: "); 
      System.out.println(table == null ? 0 : table.length); 
      } 

     } 
    //when to increase the hashmap size is calculated by capacity of hashmap divided by load factor: 
    public static double loadFactor(Map studentMap){ 
    double count = studentMap.size(); 
     double load = count/mapcapacity(studentMap); 
     return load; 
    } 
    //if the size of the map is greater than the map capacity * load factor - then double the size of map. 
    public static Integer mapcapacity(Map studentMap){ 
     //default capacity and load factor 
     Integer initCapacity= 11; 
     float loadFactor=0.75f; 
     boolean capacityFound=false; 
     Integer capacity=initCapacity; 
     Integer size=studentMap.size(); 
     while(!capacityFound){ 
      if(size>capacity*loadFactor){ 
       //increase capacity 
       capacity=capacity * 2; 
       vartrue = true; 
      } 
      else { 
       capacityFound=true; 
      } 
     } 
     return capacity; 
    } 




    //linear probing 
    public static int hashThis(String key, Map studentMap) { 
     return key.hashCode()& 0x7fffffff % mapcapacity(studentMap); 
    } 
    public static int linear(Map studentMap, String key){ 
    String value = studentMap.get(key).toString(); 
    int counter = 0; 
    int hash = hashThis(key, studentMap); 
    if (value != null) 
    { 
    hash = (hash + 1) % mapcapacity(studentMap); 
    counter ++; 
    } 
    else{ 
     return 0; 
    } 
    return hash; 
    } 


} 

回答

0

據我瞭解,你決定手動實現自己的哈希表,而不是使用java.util.HashMap,這已經是一個線性探測的方式運行。 在這種情況下,java.util.HashMap的來源可能是一個很大的提示。從「grepcode.com」網站,我發現put(K key, V value)方法的源代碼java.util.HashMap如下;

public V put(K key, V value) { 
    ... // null check on key : omitted 

    int hash = hash(key.hashCode()); 
    int i = indexFor(hash, table.length); 

    for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
     Object k; 
     if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
      ... // if the same key already exists, return the old value : omitted 
     } 
    } 
    modCount++; 
    addEntry(hash, key, value, i); 
    return null; 
} 

addEntry()之前被調用,for語句迭代搜索可用空間。 (即,退出for循環時,i表示新條目的可用空間的索引。)爲了更好地理解,您還可以檢查get()(雙重方法put())。

我認爲,這裏最重要的是java.util.HashMap似乎並沒有「改變哈希碼」的線性探測。這是與您的方法的主要區別,因爲您的代碼中的linear()似乎會針對給定的key調整hash,每當散列值的空間已被佔用時。

此外,代碼中的linear()不使用迭代搜索空閒空間,但mapcapacity()確實可用於大小擴展。這可能會導致對單個鍵插入進行多次空間調整,因此看起來不像是一種線性問題的有效方法。

總之,我想建議檢查java.util.HashMap或相關類的源代碼;)