-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 18, 19
-
b15
-
generic
-
generic
-
Verified
ADDITIONAL SYSTEM INFORMATION :
failed on all java 8, 11, and 17
tested only on windows 10.
A DESCRIPTION OF THE PROBLEM :
sometimes HashMap.putAll would cause the hashmap.table be double length than should be.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
for jdk 8-:
just run the tests I provided and see the results.
for jdk 9+:
make a break point before the System.out.println("a : " + getArrayLength(a));
then see values of a.table.length, b.table.length, c.table.length, d.table.length using debugger tool.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
for jdk 8-:
the output should be
a : 16
b : 16
c : 16
d : 16
for jdk 9+:
a.table.length = 16
b.table.length = 16
c.table.length = 16
d.table.length = 16
ACTUAL -
for jdk 8-:
the output should be
a : 16
b : 16
c : 32
d : 32
for jdk 9+:
a.table.length = 16
b.table.length = 16
c.table.length = 32
d.table.length = 32
---------- BEGIN SOURCE ----------
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
HashMap<Object, Object> a = new HashMap<>();
fill12(a);
HashMap<Object, Object> b = new HashMap<>(12);
fill12(b);
HashMap<Object, Object> c = new HashMap<>(a);
HashMap<Object, Object> d = new HashMap<>();
d.putAll(a);
System.out.println("a : " + getArrayLength(a));
System.out.println("b : " + getArrayLength(b));
System.out.println("c : " + getArrayLength(c));
System.out.println("d : " + getArrayLength(d));
}
public static void fill12(Map<Object, Object> map) {
for (int i = 0; i < 12; i++) {
map.put(i, i);
}
}
public static int getArrayLength(Map<Object, Object> map) throws NoSuchFieldException, IllegalAccessException {
Field field = HashMap.class.getDeclaredField("table");
field.setAccessible(true);
Object table = field.get(map);
return Array.getLength(table);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
change the original calculation from (int) (expected / 0.75F + 1) to (int) Math.ceil(expected / 0.75)
FREQUENCY : always
failed on all java 8, 11, and 17
tested only on windows 10.
A DESCRIPTION OF THE PROBLEM :
sometimes HashMap.putAll would cause the hashmap.table be double length than should be.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
for jdk 8-:
just run the tests I provided and see the results.
for jdk 9+:
make a break point before the System.out.println("a : " + getArrayLength(a));
then see values of a.table.length, b.table.length, c.table.length, d.table.length using debugger tool.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
for jdk 8-:
the output should be
a : 16
b : 16
c : 16
d : 16
for jdk 9+:
a.table.length = 16
b.table.length = 16
c.table.length = 16
d.table.length = 16
ACTUAL -
for jdk 8-:
the output should be
a : 16
b : 16
c : 32
d : 32
for jdk 9+:
a.table.length = 16
b.table.length = 16
c.table.length = 32
d.table.length = 32
---------- BEGIN SOURCE ----------
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class TestMap {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
HashMap<Object, Object> a = new HashMap<>();
fill12(a);
HashMap<Object, Object> b = new HashMap<>(12);
fill12(b);
HashMap<Object, Object> c = new HashMap<>(a);
HashMap<Object, Object> d = new HashMap<>();
d.putAll(a);
System.out.println("a : " + getArrayLength(a));
System.out.println("b : " + getArrayLength(b));
System.out.println("c : " + getArrayLength(c));
System.out.println("d : " + getArrayLength(d));
}
public static void fill12(Map<Object, Object> map) {
for (int i = 0; i < 12; i++) {
map.put(i, i);
}
}
public static int getArrayLength(Map<Object, Object> map) throws NoSuchFieldException, IllegalAccessException {
Field field = HashMap.class.getDeclaredField("table");
field.setAccessible(true);
Object table = field.get(map);
return Array.getLength(table);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
change the original calculation from (int) (expected / 0.75F + 1) to (int) Math.ceil(expected / 0.75)
FREQUENCY : always
- relates to
-
JDK-8282120 optimal capacity tests and test library need to be cleaned up
- Resolved
-
JDK-8186958 Need method to create pre-sized HashMap
- Resolved
-
JDK-8282178 Replace simple iterations of Map.entrySet with Map.forEach calls
- Closed