所以我试图在我的线性方法中检测碰撞,这是哈希哈希映射studentMap的键。我有线性探测的基本功能,但我正在努力检测一个键是否已经存在(因此+ 1)。到目前为止,这段代码不起作用 - 它不会检查我的地图studentMap中的密钥是否存在。 任何帮助非常感谢!我删除了一些其他哈希方法,以减少此代码的大小,因为它们无关紧要。
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 :(得分: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()
似乎调整了给定hash
的{{1}},每当哈希值的空间已经被采用时。
此外,代码中的key
不会使用迭代来搜索可用空间,但linear()
会进行大小扩展。这可能会导致单个键插入的多个空间调整,因此似乎不是线性探测的有效方法。
总之,我建议检查mapcapacity()
或相关类的源代码;)