Thursday, November 17, 2011

Case-Insensitive Map


Apache Commons Case-Insensitive Map


Problem
You may have a requirement for fetching values with String keys that will ignore the capitalization of a key when retrieving a value. Say for example to want a Mapping of Currency Names with Currency Code (But the Currency codes should be case insensitive i.e Usd,USD,usD,usd all should fetch me “US Dollar”)

This is useful when an application is requesting a Currency from a user in a form to capture the Payment Details . If a user enters "USD," "Usd," or "usd," you need to be able to return "US Dollar".

Our Own Google.com


Solution to the Problem is ready-to-wear
We can use a CaseInsensitiveMap from the Commons Collections. Let is say Thanks to the developer of Apache Foundation who do this free of “Cost”. This implementation of Map takes String keys and provides case-insensitive access. An entry with a key "USD" can be retrieved with the strings "USD," "Usd," and "USd." Here is a small example demonstrating the case insensitivity:

public static void main(String[] args) {
            CaseInsensitiveMap currencyMapping = new CaseInsensitiveMap();
            currencyMapping.put("USD","US Dollar");
            currencyMapping.put("EuR","Euro");
            currencyMapping.put("gbP","British Pound");
            currencyMapping.put("InR","Indian Rupee");
            currencyMapping.put("AUd","Australian Dollar");
            currencyMapping.put("CAD","Canadian Dollar");
            currencyMapping.put("CHF","Swiss Franc");
            currencyMapping.put("AED","Emirati Dirham");
            currencyMapping.put(1,"Dirty Value");
            System.out.println(currencyMapping.get("USD"));
            System.out.println(currencyMapping.get("usd"));
            System.out.println(currencyMapping.get("INR"));
            System.out.println(currencyMapping.get(1));
           
      }
Output is:
US Dollar        // Because its case insensitive
US Dollar         // Because its case insensitive
Indian Rupee      // Because its case insensitive
Dirty Value       // The map does not stops us from Entering Integer keys  but Output holds good only for String.
Discussion
Above example demonstrates the use of CaseInsensitiveMap to access currency names by currency abbreviations regardless of capitalization. Here is a small TWIST in the below example. For people who understand java well this should be very trivial.

public static void main(String[] args) {
            CaseInsensitiveMap currencyMapping = new CaseInsensitiveMap();
            currencyMapping.put("USD","US Dollar");
            currencyMapping.put("usd","us Dollar");
            currencyMapping.put("UsD","Us Dollar");
            System.out.println(currencyMapping.get("USD"));
            System.out.println(currencyMapping.get("usd"));
            System.out.println(currencyMapping.get("UsD"));
      }

Output is:
Us Dollar //Last Key overwrites the mapping
Us Dollar
Us Dollar

This is due to the fact that CaseInsensitiveMap is a HashMap implementation,before putting any key-value pair in the map it follows the below steps:

    1)      Converts the Key to lower case
    2)      Calls the hashcode on the lower case key
    3)      Now insert the value corresponding to this hashcode.

It performs exactly the same steps while fetching the value from the map. 

    1)      Converts the Key to lower case
    2)      Calls the hashcode on the lower case key
    3)      Fetched the corresponding value stored at this hashcode.

For API Refer below URL

1 comment:

  1. Thanks for providing good article on Case-Insensitive Map . http://www.blogercup.com/

    ReplyDelete