对 Map<String, List<String>> 类型的映射中的值进行排序

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

我有一张地图

Map<String, List<String>>

我想对每个列表中的元素进行排序。不需要对地图进行排序,但是需要对地图的每个列表进行排序,即独立对值进行排序。希望我清楚。

我尝试在地图上使用 keySet 和 entrySet 元素,但是出现以下错误:

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)

看起来我正在尝试排序的列表中有 null

有没有办法对其中包含 null 的列表进行排序?

您可以像这样遍历 Map 的键集:

Map<String, List<String>> map;

for(String s : map.keySet()){
    Collections.sort(map.get(s));
}

迭代地图值并排序,

 for(List<String> e : map.values()){
    Collections.sort(e);
 }

假设您有这样的地图:

Map<String, List<String>> map = new HashMap<String, List<String>>();
map = putMyStuffInTheMap();

您应该迭代要排序的列表,然后只对它们进行排序:

Collection<List<String>> listsFromTheMap = map.values();    
for (List<String> listFromTheMap : listsFromTheMap) {
        Collections.sort(listFromTheMap);
}

就是这样。希望对你有帮助。

由于您要排序的列表可以包含 null,并且您不能在 null 上调用 compareTo(因为它没有任何方法或字段),您将需要提供您自己的比较器,它将处理 null 并将其与排序方法一起使用。

例如,如果您想将 null 放在升序的末尾,您需要实施如下规则:

  • null null - 不要交换,没有意义 (return 0)
  • null "someString" - 交换,null 更大,应放在 "someString" 之后 (return 1)
  • "someString" null - 不要交换,第一个参数 ("someString") 小于 null (return -1)
  • "string1" "string2" - return 比较两个非空值的默认结果

你的比较器看起来像

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);
    }
};

现在可以使用了

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

Java 8 次更新

因为 Java 8 Comparator 提供了可以包装其他比较器并创建另一个将空值放置在我们集合的开头或结尾的方法。这些方法是:

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

sotr(Comparator) 方法也被添加到 List 接口,这意味着我们不需要显式调用 Collections.sort(list,comparator).

因此您的代码可以如下所示:

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

但是没有什么能阻止您使用其他比较器而不是 Comparator.naturalOrder(),例如 String.CASE_INSENSITIVE_ORDER 中存储的比较器,现在也可以使用 String::compareToIgnoreCase 方法参考创建。