Question on HashMap change in 8011200

Shi Jun Zhang zhangshj at
Thu Jun 27 08:02:09 UTC 2013


There are some isEmpty() check added into get/remove methods since 
8011200 to return directly if HashMap is empty. However isEmpty is a 
non-final public method which can be overridden by subclass. If the 
subclass defines isEmpty differently from HashMap, it would cause 
problem while getting or removing elements.

For example, here is a simple test case, the subclass of HashMap always 
has at least one key value pair so isEmpty will never be false.


import java.util.HashMap;

public class HashMapTest {
     public static class NotEmptyHashMap<K,V> extends HashMap<K,V> {
         private K alwaysExistingKey;
         private V alwaysExistingValue;

         public V get(Object key) {
             if (key == alwaysExistingKey) {
                 return alwaysExistingValue;
             return super.get(key);

         public int size() {
             return super.size() + 1;

         public boolean isEmpty() {
             return size() == 0;

     public static void main(String[] args) {
         NotEmptyHashMap<String, String> map = new NotEmptyHashMap<>();

The test can end successfully before 8011200 but it will throw 
ArrayIndexOutOfBoundsException after 8011200. The reason is isEmpty() 
check in HashMap.getEntry() method gets passed but the actual table 
length is 0. I think the real intention of isEmpty() check is to check 
whether size in HashMap is 0 but not whether the subclass is empty, so I 
suggest to use "size == 0" instead of "isEmpty()" in get/remove methods.

Do you think this is a bug or a wrong usage of extending HashMap? I find 
there is a similar usage in javax.swing.MultiUIDefaults which extends 


Shi Jun Zhang

More information about the core-libs-dev mailing list