对 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<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
。
有什么方法可以对包含 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<string,string>>排序,要求可以按照正序、逆序排序(代码写不出来可以写原理)