Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort the values in a map of type Map<String, List<String>>

I have a map of type

Map<String, List<String>>

I want to sort the elements in each List. No need to sort the map, but, need to sort each list of the map i.e. sort the values independently. Hope I am clear.

I tried using keySet and entrySet elements on a Map, but, getting the following error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at java.util.ComparableTimSort.binarySort(ComparableTimSort.java:232)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:176)
    at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
    at java.util.Arrays.sort(Arrays.java:472)
    at java.util.Collections.sort(Collections.java:155)

Looks like I am having null in the List I am trying to sort.

Is there any way to sort a List having null in it?

like image 932
vijayinani Avatar asked Aug 31 '25 17:08

vijayinani


2 Answers

Since list you want to sort can contain null and you can't call compareTo on null (since it doesn't have any methods nor fields) you will need to provide your own Comparator which will handle null and use it with sorting method.

For instance if you would like to place null at end of ascending order you will need to implement rules like:

  • null null - don't swap, there is no point (return 0)
  • null "someString" - swap, null is bigger and should be placed after "someString" (return 1)
  • "someString" null - don't swap, first argument ("someString") is smaller than null (return -1)
  • "string1" "string2" - return default result of comparing both non-null values

and your Comparator can look like

Comparator<String> myComparator = new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        if (s1==null && s2==null) return 0;//swapping has no point here
        if (s1==null) return  1;
        if (s2==null) return -1;
        return s1.compareTo(s2);
    }
};

Now you can use it

for (List<String> list : yourMap.values()) {
    Collections.sort(list, myComparator);
}

Java 8 update

Since Java 8 Comparator provides methods which can wrap other comparator and create another one which will place nulls at start or end of our collection. This methods are:

  • Comparator.nullsFirst(Comparator)
  • Comparator.nullsLast(Comparator)

Also sort(Comparator) method was added to List interface which means we don't need to call explicitly Collections.sort(list,comparator).

So your code can look like:

for (List<String> list : yourMap.values()) {
    list.sort(Comparator.nullsLast(Comparator.naturalOrder()));
}

But nothing stops you from using other comparator instead of Comparator.naturalOrder() like one stored in String.CASE_INSENSITIVE_ORDER which now can also be created with String::compareToIgnoreCase method reference.

like image 180
Pshemo Avatar answered Sep 02 '25 06:09

Pshemo


Iterate over map values and sort,

 for(List<String> e : map.values()){
    Collections.sort(e);
 }
like image 20
Masudul Avatar answered Sep 02 '25 07:09

Masudul