简体   繁体   中英

Number of entries in HashMap bucket

有没有办法确定我们在HashMap拥有哪些存储桶,以及它们包含多少个条目?

Not directly: this is an implementation detail hidden through use of private fields.

If you have access to source code of your JDK, you could use reflection API to access private variables of your HashMap<K,V> , which would let you get bucket count and the content of individual buckets. Your code would be non-portable, though, because it would break encapsulation of a library class.

You can do it by reflection but it is very jdk specific. This one works with small maps Java 8 but will probably break when the map gets bigger because I believe Java 8 uses a hybrid mechanism when the buckets get full.

private void buckets(HashMap<String, String> m) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    // Pull out the table.
    Field f = m.getClass().getDeclaredField("table");
    f.setAccessible(true);
    Object[] table = (Object[]) f.get(m);
    int bucket = 0;
    // Walk it.
    for (Object o : table) {
        if (o != null) {
            // At least one in this bucket.
            int count = 1;
            // What's in the `next` field?
            Field nf = o.getClass().getDeclaredField("next");
            nf.setAccessible(true);
            Object n = nf.get(o);
            if (n != null) {
                do {
                    // Count them.
                    count += 1;
                } while ((n = nf.get(n)) != null);
            }
            System.out.println("Bucket " + bucket + " contains " + count + " entries");
        }
        bucket += 1;
    }
}

public void test() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
    HashMap<String, String> m = new HashMap<>();
    String[] data = {"One", "Two", "Three", "Four", "five"};
    for (String s : data) {
        m.put(s, s);
    }
    buckets(m);
}

Prints:

Bucket 7 contains 2 entries
Bucket 13 contains 2 entries
Bucket 14 contains 1 entries

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM