调整Java中地图的行为大小



我需要知道Java放大的地图何时。为此,我需要一个公式来计算良好的初始容量。

在我的项目中,我需要一个包含大对象的大型地图。因此,我想通过指定合适的初始容量来防止调整地图的大小。通过反思,我研究了地图的行为。

package com.company;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Main {
    public static void main(String[] args) {
        Map m  = new HashMap();
        int lastCapacity = 0, currentCapacity = 0;
        for (int i = 1; i <= 100_000; i++) {
            m.put(i,i);
            currentCapacity = getHashMapCapacity(m);
            if (currentCapacity>lastCapacity){
                System.out.println(lastCapacity+" --> "+currentCapacity+" at "+i+" entries.");
                lastCapacity=currentCapacity;
            }
        }
    }
    public static int getHashMapCapacity(Map m){
        int size=0;
        Field tableField = null;
        try {
            tableField = HashMap.class.getDeclaredField("table");
            tableField.setAccessible(true);
            Object[] table = (Object[]) tableField.get(m);
            size = table == null ? 0 : table.length;
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return size;
    }
}

输出为:

0->在1个条目中16。

16-> 32个条目。

32->在25个条目时64。

64-> 128在49个条目中。

128-> 256在97条目中。

256-> 512在193个条目。

512-> 1024在385条目中。

1024-> 2048在769条目。

2048-> 4096在1537条目。

4096-> 8192在3073条目。

8192-> 16384在6145条目。

16384-> 32768在12289条目。

32768-> 65536在24577条目中。

65536-> 131072在49153条目。

131072-> 262144在98305条目。

我可以假设地图总是以这种方式行为?Java 7和Java 8之间有任何区别吗?

查看这种行为的最简单方法是查看OpenJDK源。它们都是免费的,相对易于阅读。

在这种情况下,检查hashmap,您会看到一些广泛的实施说明可以解释尺寸的工作方式,将载荷因子用作阈值(这是您所看到的行为(,甚至决定的决定是如何的制作是否将树木用于垃圾箱。通读,如果不清楚,请回来。

通过扩展非常便宜的操作,该代码非常优化。我建议使用个人资料来获得一些证据,表明在进行任何调整之前,性能问题与扩展有关。

根据文档:

在设置其初始容量时,应考虑地图中预期的条目及其负载因子,以最大程度地减少重新操作的数量。如果初始容量大于最大条目数除以负载因子,则不会发生重新操作。https://docs.oracle.com/javase/8/docs/api/java/java/util/hashmap.html

最新更新