【问题标题】:Sort the values in a map of type Map<String, List<String>>对 Map<String, List<String>> 类型的映射中的值进行排序
【发布时间】:2015-06-19 01:36:19
【问题描述】:

我有一张类型的地图

Map&lt;String, List&lt;String&gt;&gt;

我想对每个 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

有什么方法可以对包含 null 的 List 进行排序?

【问题讨论】:

  • 不清楚。对所有列表中的所有元素进行排序并将结果添加到新列表中?单独对每个列表进行排序?

标签: java list collections hashmap


【解决方案1】:

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

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

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

你的 Comparator 看起来像

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】:

    假设你的地图是这样的:

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

    就是这样。希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      遍历地图值并排序,

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

      【讨论】:

        【解决方案4】:

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

        Map<String, List<String>> map;
        
        for(String s : map.keySet()){
            Collections.sort(map.get(s));
        }
        

        【讨论】:

        猜你喜欢
        • 2015-01-18
        • 1970-01-01
        • 2021-03-26
        • 2019-05-29
        • 2019-11-27
        • 2014-09-27
        • 2018-12-07
        • 2016-11-25
        相关资源
        最近更新 更多