Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何获得Java Hashmap上冲突数量的度量?_Java_Hashmap_Hash - Fatal编程技术网

如何获得Java Hashmap上冲突数量的度量?

如何获得Java Hashmap上冲突数量的度量?,java,hashmap,hash,Java,Hashmap,Hash,我正在实现一个自定义哈希函数,如果我在一个HashMap bucket中获得了大量冲突,我如何知道bucket中存储了多少元素?没有内置的方法来确定是否发生了冲突。您必须研究集合(HashMap)如何将hashCode值分配给bucket,并自己镜像流程,监视插入以跟踪冲突。您可以编写一些反射代码来访问HashMap的内部存储桶并自己检查它们。API中没有对此的直接支持。用于存储存储桶的成员变量table,甚至不是公共的,因此扩展类不会让您走得更远 假设您正在评估哈希函数,而不是在生产代码中执行

我正在实现一个自定义哈希函数,如果我在一个HashMap bucket中获得了大量冲突,我如何知道bucket中存储了多少元素?

没有内置的方法来确定是否发生了冲突。您必须研究集合(HashMap)如何将hashCode值分配给bucket,并自己镜像流程,监视插入以跟踪冲突。

您可以编写一些反射代码来访问HashMap的内部存储桶并自己检查它们。

API中没有对此的直接支持。用于存储存储桶的成员变量
table
,甚至不是公共的,因此扩展类不会让您走得更远

假设您正在评估哈希函数,而不是在生产代码中执行此操作,则可以使用反射传递这些约束

我设法把桶里的东西打印出来。从这一点上分析分布指标应该不难。代码如下:

测试驱动程序:

import java.lang.reflect.Field;
import java.util.*;

class Test {

    public static void main(String[] args) throws Exception {

        SubHashMap<String, Integer> map = new SubHashMap<String, Integer>();

        map.put("zero",  0); map.put("one",   1); map.put("two", 2);
        map.put("three", 3); map.put("four",  4); map.put("five", 5);
        map.put("six",   6); map.put("seven", 7); map.put("eight", 8);

        map.dumpBuckets();
    }

}
class SubHashMap<K, V> extends HashMap<K, V> {

    public void dumpBuckets() throws Exception {

        Field f = HashMap.class.getDeclaredField("table");
        f.setAccessible(true);

        Map.Entry<K, V>[] table = (Map.Entry<K, V>[]) f.get(this);

        Class<?> hashMapEntryClass = null;
        for (Class<?> c : HashMap.class.getDeclaredClasses())
            if ("java.util.HashMap.Entry".equals(c.getCanonicalName()))
                hashMapEntryClass = c;

        Field nextField = hashMapEntryClass.getDeclaredField("next");
        nextField.setAccessible(true);

        for (int i = 0; i < table.length; i++) {

            System.out.print("Bucket " + i + ": ");
            Map.Entry<K, V> entry = table[i];

            while (entry != null) {
                System.out.print(entry.getKey() + " ");
                entry = (Map.Entry<K, V>) nextField.get(entry);
            }

            System.out.println();
        }
    }
}
Bucket 0: 
Bucket 1: two 
Bucket 2: 
Bucket 3: seven five 
Bucket 4: 
Bucket 5: 
Bucket 6: 
Bucket 7: one 
Bucket 8: three 
Bucket 9: 
Bucket 10: 
Bucket 11: four 
Bucket 12: zero 
Bucket 13: 
Bucket 14: eight 
Bucket 15: six 

不完全是重复的,但类似的帖子可以使用反射绕过访问限制。看看我的答案。