限制Java中HashMap的最大大小

and*_*and 31 java hashmap

我想限制a的最大大小,HashMap以便对我正在实现的各种散列算法采用指标.我查看了一个HashMap重载构造函数中的loadfactor .

HashMap(int initialCapacity, float loadFactor) 
Run Code Online (Sandbox Code Playgroud)

我尝试在构造函数中将loadFactor设置为0.0f(意味着我不希望HashMap的大小增长为EVER),但javac调用此无效:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal load factor: 0.0
        at java.util.HashMap.<init>(HashMap.java:177)
        at hashtables.CustomHash.<init>(Main.java:20)
        at hashtables.Main.main(Main.java:70) Java Result: 1
Run Code Online (Sandbox Code Playgroud)

有没有另一种限制大小的方法,HashMap所以它不会增长?

Whi*_*g34 119

您可以创建一个这样的新类来限制HashMap的大小:

public class MaxSizeHashMap<K, V> extends LinkedHashMap<K, V> {
    private final int maxSize;

    public MaxSizeHashMap(int maxSize) {
        this.maxSize = maxSize;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > maxSize;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1提及LinkedHashMap类,removeEldestEntry()和*内置*功能来维护这种类型的地图!请参阅:http://docs.oracle.com/javase/1.4.2/docs/api/java/util/LinkedHashMap.html#removeEldestEntry(java.util.Map.Entry) (13认同)
  • 以前的java链接死了 - http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashMap.html#removeEldestEntry(java.util.Map.Entry) (3认同)
  • 只是为了澄清,如果我理解正确的话,这样当您插入一个新元素时,它只会从地图中删除最旧的元素,然后插入新的元素,从而将大小限制为“maxSize”。这并不是说它不允许您添加新元素。 (2认同)

Mik*_*ike 36

有时候更简单更好.

public class InstrumentedHashMap<K, V> implements Map<K, V> {

    private Map<K, V> map;

    public InstrumentedHashMap() {
        map = new HashMap<K, V>();
    }

    public boolean put(K key, V value) {
        if (map.size() >= MAX && !map.containsKey(key)) {
             return false;
        } else {
             map.put(key, value);
             return true;
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*gus 6

简单的解决方案通常是最好的,因此使用不可修改不可变的 hashmap.

如果你不能改变元素的数量,那么大小将被修复 - 问题解决了.


Cle*_*lin 6

我尝试在构造函数中将 loadFactor 设置为 0.0f(这意味着我不希望 HashMap 的大小永远增长),但javac将此称为无效

A loadFactorof 的1.0f意思是“直到 HashMap 100% 满才增长”。如果被接受,a loadFactorof就意味着“呈指数级增长”,这就是为什么它没有被接受。0.0f

来自HashMap 文档

容量是哈希表中桶的数量,初始容量就是创建哈希时的容量。负载因子是衡量哈希表在其容量自动增加之前允许达到的满度的指标。当哈希表中的条目数超过负载因子与当前容量的乘积时,哈希表将被重新哈希(即重建内部数据结构),使得哈希表的桶数大约为两倍。

示例:使用默认设置初始化的 HashMap 的容量为 16,负载因子为0.75fCapacity * load factor = 16 * 0.75 = 12。因此,将第 13 个项目添加到 HashMap 将导致它增长到(大约)32 个存储桶。

无效示例:初始化容量为 16、负载因子为 的 HashMap 0.0fCapacity * load factor = 16 * 0 = 0。因此,每次尝试添加项目都会触发重新散列并使大小加倍,直到内存耗尽。

你最初想要的:

如果初始容量大于最大条目数除以负载因子,则不会发生重新哈希操作。

如果你创建一个容量 M > N、负载因子为 1 的 HashMap,并添加 N 个项目,它就不会增长。

Map<KeyType, ValueType> nonGrowingHashMap = new HashMap<>(MAXIMUM_MAP_SIZE, 1.0f);
Run Code Online (Sandbox Code Playgroud)