Issue
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?
Solution
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 thannull
(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.
Answered By - Pshemo
Answer Checked By - Cary Denson (JavaFixing Admin)