Search code examples
javacasesuperclass

Case insensitive hashmap for strings in java


I came across this post for a case insensitive hashmap and tried to implement it but I'm not getting the expected result. For some reason it's not returning the value when I do get with a different casing and is returning null, and I thought that you didn't really need a non-default constructor in this case but I'm not sure.

public class CaseInsensitiveMap extends HashMap<String, Integer> {

    @Override
    public Integer put(String key, Integer value) {
       return super.put(key.toLowerCase(), value);
    }

    // not @Override because that would require the key parameter to be of type Object
    public Integer get(String key) {
       return super.get(key.toLowerCase());
    }
}

and used like so;

HashMap<String, Integer> stuff = new CaseInsensitiveMap();
stuff.put("happy", 11);
System.out.println(stuff);
Integer result = stuff.get("HAPPy");
System.out.println(result);
System.out.println(stuff);

but result is;

{happy=11}
null
{happy=11}

Solution

  • Simple fix;

    CaseInsensitiveMap stuff = new CaseInsensitiveMap();
    

    prints out;

    {happy=11}
    11
    {happy=11}
    

    CaseInsensitiveMap is extending HashMap<String, Integer> so it is a subclass of it, the fact that you reference stuff as HashMap (as the superclass) allows it to use default get method. You can even see in an IDE that your custom get(String) in CaseInsensitiveMap is not even used.

    Only overridden methods will be used if you use superclass reference for a subclass, as you've done in your code. That is why only your custom put(String, Integer) method works since it is overriding the method in super.

    Referencing Subclass objects with Subclass vs Superclass reference for more info on that issue.