在Map <string,list <string =“”>&gt; </string,>类型的地图中对值进行排序

时间:2015-04-13 16:33:23

标签: java list collections hashmap

我有一张类型

的地图

Map<String, List<String>>

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

我尝试在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

有没有办法对List中的null进行排序?

4 个答案:

答案 0 :(得分:3)

迭代地图值并排序,

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

答案 1 :(得分:3)

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

例如,如果您希望将null放在升序结尾处,则需要实施以下规则:

  • null null - 不要交换,没有意义(返回0)
  • null "someString" - swap,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提供了可以包装其他比较器并创建另一个比较器的方法,这些方法将在我们的集合的开头或结尾放置空值。这种方法是:

  • 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方法参考创建。

答案 2 :(得分:0)

您可以像这样迭代Map的密钥集:

Map<String, List<String>> map;

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

答案 3 :(得分: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);
}

就是这样。希望它有所帮助。