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

Posted

技术标签:

【中文标题】对 Map<String, List<String>> 类型的映射中的值进行排序【英文标题】:Sort the values in a map of type 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 进行排序?

【问题讨论】:

不清楚。对所有列表中的所有元素进行排序并将结果添加到新列表中?单独对每个列表进行排序? 【参考方案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));

【讨论】:

虽然它是正确的,但根据Performance considerations for keySet() and entrySet() of Map,我会使用entrySet 而不是keySet

以上是关于对 Map<String, List<String>> 类型的映射中的值进行排序的主要内容,如果未能解决你的问题,请参考以下文章

对list中map中的key值进行排序

map,list

list<map> 排序,根据总分数排序,高手来,加分

对List<Map<string,string>>排序,要求可以按照正序、逆序排序(代码写不出来可以写原理)

怎么实现对List<Map<String, Object>>内容的清空

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