2017-03-10 3 views
1

Also versuche ich auf Kollisionen in meiner linearen Methode zu erkennen, die die Schlüssel meiner Hash-Map studentMap Hashing ist. Ich habe die Grundfunktion für das lineare Sondieren, aber ich habe Mühe herauszufinden, ob bereits ein Schlüssel vorhanden ist (und daher + 1). Bis jetzt funktioniert dieser Code nicht - er überprüft nicht den Schlüssel von meiner map studentMap, ob er da ist oder nicht. Jede Hilfe sehr geschätzt! Ich habe einige der anderen Hash-Methoden entfernt, um die Größe dieses Codes zu reduzieren, da sie irrelevant sind.Kollisionsauflösung Lineares Sondieren 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; 
    } 


} 

Antwort

0

Soweit ich verstehe, haben Sie beschlossen, Ihre eigene Hash-Karte manuell zu implementieren, anstatt java.util.HashMap verwenden, die bereits in einer linearen Sondieren Weise ausgeführt wird. In diesem Fall könnte die Quelle von java.util.HashMap ein großer Hinweis sein. Von der Website "grepcode.com" fand ich Quellcodes von put(K key, V value) Methode von java.util.HashMap wie folgt;

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; 
} 

Bevor addEntry() genannt wird, ist for Anweisung für einen freien Raum iteriert suchen. (Beim Verlassen der for Schleife zeigt i einen Index für einen verfügbaren Platz für den neuen Eintrag an.) Zum besseren Verständnis können Sie auch get(), die duale Methode put(), überprüfen.

Ich denke, die wichtigste Sache hier für Sie ist, dass java.util.HashMap scheint nicht "den Hashcode" für lineare Sondierung zu ändern. Dies ist der Hauptunterschied zu Ihrem Ansatz, da linear() in Ihrem Code die hash für einen gegebenen key zu justieren scheint, immer wenn der Platz für den Hash-Wert bereits vergeben ist.

Darüber hinaus verwendet linear() in Ihrem Code keine Iteration zum Suchen eines freien Speicherplatzes, aber mapcapacity() tut für die Größenerweiterung. Dies könnte zu einer mehrfachen Speicherplatzanpassung für eine einzelne Schlüsseleinfügung führen, scheint also kein effizienter Weg für lineares Probling zu sein.

Zusammenfassend möchte ich vorschlagen, die Quellcodes von java.util.HashMap oder verwandten Klassen zu überprüfen;)

Verwandte Themen