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

4

我有一个类型为

Map<String, List<String>>

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

我尝试在Map上使用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的列表进行排序?


不清楚。是将所有列表中的元素排序并将结果添加到新列表中吗?还是独立地对每个列表进行排序? - Chetan Kinger
4个回答

4
由于您想要排序的列表可能包含null,而且您不能调用null上的compareTo(因为它没有任何方法或字段),您需要提供自己的比较器来处理null并将其与排序方法一起使用。
例如,如果您希望将null放置在升序的末尾,则需要实现以下规则:
- null null - 不交换,没有意义(返回0) - null "someString" - 交换,null更大,应该放在"someString"之后(返回1) - "someString" null - 不交换,第一个参数("someString")小于null(返回-1) - "string1" "string2" - 返回比较两个非空值的默认结果
您的比较器可以如下所示:
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提供了一些方法,可以包装其他比较器并创建另一个比较器,该比较器将null放置在我们的集合的开头或结尾。这些方法包括:

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

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

因此,您的代码看起来可能像这样:

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

但是您可以使用其他比较器而不是Comparator.naturalOrder(),例如存储在String.CASE_INSENSITIVE_ORDER中的比较器,现在也可以使用String::compareToIgnoreCase方法引用来创建。


3

遍历 map 的值并进行排序,

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

0
您可以像这样迭代Map的键集:

Map<String, List<String>> map;

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

1
虽然根据《Map的keySet()和entrySet()的性能考虑》(https://dev59.com/3G865IYBdhLWcg3wU8-I)这篇文章是正确的,但我会使用`entrySet`而不是`keySet`。 - Albert

0

假设你有这样的地图:

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

就是这样了。希望能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接