Home > Software design >  Why does this code throw Exception in thread "main" java.lang.OutOfMemoryError: Java heap
Why does this code throw Exception in thread "main" java.lang.OutOfMemoryError: Java heap

Time:01-20

import java.util.HashMap;
import java.util.HashSet;

public class ComputeIfAbsentWithHashSetNew {
    public static void main(String[] args) {
        var map = new HashMap<Integer, HashSet<Integer>>();
        var data = new int[][]{{305589003, 4136}, {305589004, 4139}};
        for (var entry : data) {
            int x = entry[0];
            int y = entry[1];
//            map.computeIfAbsent(x, _x -> new HashSet<>()).add(y); // ----- line 1
            var k = map.computeIfAbsent(x, HashSet::new);           // ----- line 2
            k.add(y);
        }
    }
}

Above code throws at jdk 17、 18、 19:

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

When debug, I see the newCap in Hashmap::resize() is very large, I don't know why. I thought both the lines do same thing previously.

When I replace line 2 with line 1 in code, it runs successfully.

CodePudding user response:

HashSet::new is a method reference pointing to new HashSet(initialCapacity). See the java-doc of HashSet.

So, it creates a bigger HashSets than you expect, because it takes your x variable as parameter.

  •  Tags:  
  • java
  • Related