Java HashMap computeIfAbsent 非法容量

Java HashMap computeIfAbsent Illegal Capacity

我有一个以 arrayList 作为其值的 hashMap。当键不在地图中时,我想使用 computeIfAbsent 方法有效地创建列表。然后我尝试使用 ArrayList::new 而不是 k -> new ArrayList<Integer>() 来使代码更清晰,但如果键是负数,则会出现“无效容量”错误。

Map<Integer, List<Integer>> map = new HashMap<>();

map.computeIfAbsent(-4, x -> new ArrayList<Integer>());//This is OK
map.computeIfAbsent(-5, ArrayList::new);//This gives error
java.lang.IllegalArgumentException: Illegal Capacity: -5

看起来密钥已传递给构造函数。谁能告诉我这是怎么发生的?在这种情况下我是否仍然可以使用方法引用来创建 arrayList?

computeIfAbsent 方法是这样定义的:

来自 class java.util.HashMap 源代码:

@Override
public V computeIfAbsent(K key,Function<? super K, ? extends V> mappingFunction) {

  ... // some code
  V v = mappingFunction.apply(key); // create value
  // ... put value into the map itself
}

所以我们在这里谈论 mappingFunction:它必须接受一个参数,它在“运行时”是一个键(computeIfAbsent 的第一个参数)

所以 Java 将此函数“匹配”到 ArrayList 的构造函数,这里接受一个 (int) 参数,因为这就是方法推断的工作方式,否则它甚至无法编译。

现在,这里是 java.util.ArrayList 的构造函数,带有一个 int 参数:

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

由于在您的示例中键是“-5”,因此在一天结束时调用此构造函数时使用“-5”。它进入“else”块,因此出现异常...

当您使用第一个构造时:

map.computeIfAbsent(-4, x -> new ArrayList<Integer>());

"x" 将解析为 -4 但没关系,因为您没有传入 ArrayList 的构造函数,或者换句话说,您不在映射函数中使用它。