确定HashTable平均链长

时间:2015-10-29 17:57:37

标签: java hashmap hashtable bucket

我正在尝试编写一些函数来显示正在使用的桶的平均数量以及哈希表中的平均链长。我不知道如何测量这些东西。

public Double bucketUsagePercentage(){

}
public Double avgChainLength(){

}

public void printStats(){
    System.out.println("LoadFactor: " + getTableLoad());
}

1 个答案:

答案 0 :(得分:1)

如前所述,您实际上可以包装Hashtable,然后跟踪插入的Object哈希码+动态计算可用桶的数量。 但是,假设您知道loadfactor(默认为0.75),您可以创建静态工具来“测量”任何现有的Hashtable(您可以轻松地将其更改为适用于HashSet)。

*只是为了突出显示由于初始容量要求,结果在开始时可能不是100%准确,因为初始存储桶是固定的,直到需要重新散列为止。

import java.util.Hashtable;

public class HashMetrics {


    public static double bucketUsagePercentage(Hashtable<?,?> a, double loadfactor) {
        int bucketSize = getBucketSize(a, loadfactor);
        int[] bucketFrequency = new int[bucketSize];
        for (Object k : a.keySet()) {
            bucketFrequency[k.hashCode() % bucketSize]++;
        }
        int counter = 0;
        for (int i : bucketFrequency) {
            if (i > 0) counter++;
        }
        return (double)counter / bucketSize;
    }

    //skip empty buckets (very similar to previous function, last line is only changed)
    public static double averageChainLength(Hashtable<?,?> a, double loadfactor) {
        int bucketSize = getBucketSize(a, loadfactor);
        int[] bucketFrequency = new int[bucketSize];
        for (Object k : a.keySet()) {
            bucketFrequency[k.hashCode() % bucketSize]++;
        }
        int counter = 0;
        for (int i : bucketFrequency) {
            if (i > 0) counter++;
        }

        return (double)a.size() / counter;
    }

    public static int log2(int number) {
        if(number == 0)
            return 0;
        return 31 - Integer.numberOfLeadingZeros(number);
    }

    public static int getBucketSize(Hashtable<?,?> a, double loadFactor) {
        int n = a.size();
        int bucketSize = 2 << log2(n);
        if (bucketSize * loadFactor <= n) {
            bucketSize <<= 1;
        }
        return bucketSize;
    }
}