Duplicate :
|
ADDITIONAL SYSTEM INFORMATION : RHEL 7.5. Java 8. A DESCRIPTION OF THE PROBLEM : The java 9 Javadoc for HashMap.computeIfAbsent() states that "The mapping function should not modify this map during computation". This is an important caveat. Unfortunately the java 8 javadocs do not include this important warning despite the fact that the method is impacted by the same issue. Worse still, the java 8 implementation of the method does not throw a ConcurrentModificationException if a mapping function modifies the map - instead it can silently result in bad entries in the Map. REGRESSION : Last worked in version 8u192 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : Run the attached source on java 8. It prints out many lines of text because the contents of the Map are not as expected. On Java 11 it crashes with a ConcurrentModificationException message (which is not strictly correct since it is a single-threaded process). EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - The test should either work or it should fail with an error or there should be a comment in the java 8 javadocs to indicate the potential problem. ACTUAL - The test fails when loadFactor is set above 1.0. ---------- BEGIN SOURCE ---------- import java.util.HashMap; public class CIF { public static HashMap<Integer, Integer> hMap = new HashMap<Integer, Integer>(2048, 100.0f); public static void main(String[] args) throws Exception { for (int i=0; i<100000; i++) { hMap.computeIfAbsent(i, k -> f(k)); // System.out.println("(2) " + i + " " + hMap.get(i)); } for (int i=0; i<200000; i++) { if (hMap.get(i) != i) { System.out.println(i + " -> " + hMap.get(i)); } } } static int f(int idx) { idx += 100000; hMap.computeIfAbsent(idx, k -> f1(k)); return idx-100000; } static int f1(int idx) { hMap.computeIfAbsent(idx-100000, k -> f2(k)); // System.out.println("(1) " + (idx-100000) + " " + hMap.get(idx-100000)); return idx; } static int f2(int idx) { return idx+1; } } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : Ensure that we do not modify the map inside the mapping function - which is not a limitation mentioned in the javadocs. FREQUENCY : always