14

Is there a Map implementation in Java that will use case-insensitive String matching for the key, but also supports the null key? I know that

new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)

supports case-insensitive matching of String keys, but it doesn't support the null key.

Boann
  • 48,794
  • 16
  • 117
  • 146
Gilo
  • 640
  • 3
  • 23
  • If you use your own class for the key it is up to you to implement `equals` and `hashCode` so that they work case insensitive. – Henry Jan 02 '18 at 17:15
  • Perhaps use `Objects.toString(key)` when inserting in the map. That will map the key to the string `null`. – Henrik Aasted Sørensen Jan 02 '18 at 17:16
  • Look at the implementation where case sensitivity is taken. – Roman C Jan 02 '18 at 17:21
  • 4
    Not sure why this is getting downvoted... – assylias Jan 02 '18 at 17:29
  • Related: [null-safe mapping Comparator using default implementations](https://stackoverflow.com/q/28499846). [How to handle nulls when using Java collection sort](https://stackoverflow.com/q/3671826). [What to do with null fields in compare()?](https://stackoverflow.com/q/128042) [comparator with null values](https://stackoverflow.com/q/2401606) – Bernhard Barker Jan 02 '18 at 19:27

3 Answers3

31

If you're on Java 8, the following will create a null-compatible, case-insensitive TreeMap:

Comparator<String> cmp = Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER);
TreeMap<String, String> map = new TreeMap<>(cmp);

No external libraries needed.

Henrik Aasted Sørensen
  • 6,966
  • 11
  • 51
  • 60
8

You can use CaseInsensitiveMap for this. This will fulfill your requirement. It is case-insensitive as well as supports null keys.

From the doc

A case-insensitive Map. Before keys are added to the map or compared to other existing keys, they are converted to all lowercase in a locale-independent fashion by using information from the Unicode data file.

Null keys are supported.

The keySet() method returns all lowercase keys, or nulls.

Shubhendu Pramanik
  • 2,711
  • 2
  • 13
  • 23
5

If you would prefer not using external libraries, you could make your own wrapper for String.CASE_INSENSITIVE_ORDER that sorts nulls in a predictable way:

 NavigableMap<String,String> m = new TreeMap(
    new Comparator<String>() {
        public int compare(String s1, String s2) {
            if (s1 == null && s2 == null) return 0;
            if (s1 != null && s2 != null) {
                return String.CASE_INSENSITIVE_ORDER.compare(s1, s2);
            }
            return s1 == null ? -1 : 1;
        }
    }
 );

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523