为什么这段代码会在线程“main”java.lang.OutOfMemoryError:Java堆空间中抛出异常?

don*_* jy 5 java

import java.util.HashMap;\nimport java.util.HashSet;\n\npublic class ComputeIfAbsentWithHashSetNew {\n    public static void main(String[] args) {\n        var map = new HashMap<Integer, HashSet<Integer>>();\n        var data = new int[][]{{305589003, 4136}, {305589004, 4139}};\n        for (var entry : data) {\n            int x = entry[0];\n            int y = entry[1];\n//            map.computeIfAbsent(x, _x -> new HashSet<>()).add(y); // ----- line 1\n            var k = map.computeIfAbsent(x, HashSet::new);           // ----- line 2\n            k.add(y);\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

上面的代码抛出 jdk 17\xe3\x80\x81 18\xe3\x80\x81 19:

\n
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space\n    at java.base/java.util.HashMap.resize(HashMap.java:702)\n    at java.base/java.util.HashMap.putVal(HashMap.java:627)\n    at java.base/java.util.HashMap.put(HashMap.java:610)\n    at java.base/java.util.HashSet.add(HashSet.java:221)\n    at _explore.ComputeIfAbsentWithHashSetNew.main(ComputeIfAbsentWithHashSetNew.java:15)\n
Run Code Online (Sandbox Code Playgroud)\n

调试时,我看到newCapinHashmap::resize()很大,我不知道为什么。我认为这两条线之前都做了同样的事情。

\n

当我将代码中的第 2 行替换为第 1 行时,它运行成功。

\n

use*_*157 5

HashSet::new是指向 的方法引用new HashSet(initialCapacity)请参阅HashSet的 java-doc 。

因此,它创建的HashSets 比您预期的要大,因为它将您的x变量作为参数。

  • 细节:`HashSet::new` 不是 lambda,而只是一个方法引用(根据 JLS [15.27. Lambda 表达式](https://docs.oracle.com/javase/specs/jls/se19/html/jls- 15.html#jls-15.27)) (4认同)