简体   繁体   English

如何使用 Java 8 按某些特定键的值对地图列表进行排序?

[英]How can I sort a list of maps by value of some specific key using Java 8?

How can I sort a List of Map<String, String> using Java 8?如何使用 Java 8 对Map<String, String> List进行排序? The map contains a key called last_name , and the value associated with it may be null .该映射包含一个名为last_name的键,与之关联的值可能为null I'm not sure how to do it because the following results in a compiler error:我不知道该怎么做,因为以下会导致编译器错误:

List<Map<String, String>> peopleList = ...

peopleList.sort(Comparator.comparing(Map::get, Comparator.nullsLast(Comparator.naturalOrder())));

Is using an anonymous class the only way to do it?使用匿名类是唯一的方法吗?

Note that I am not trying to sort each map in the list.请注意,我并不是要对列表中的每个地图进行排序。 I want to sort the list itself based on a key in each map.我想根据每个地图中的键对列表本身进行排序。

It looks like you can rewrite your code like看起来您可以像这样重写代码

peopleList.sort(Comparator.comparing(
                    m -> m.get("yourKey"), 
                    Comparator.nullsLast(Comparator.naturalOrder()))
               )

This should fit your requirement.这应该符合您的要求。

peopleList.sort((o1, o2) -> o1.get("last_name").compareTo(o2.get("last_name")));

In case you want handle the null pointer try this "old fashion" solution:如果您想处理空指针,请尝试这种“老式”解决方案:

peopleList.sort((o1, o2) ->
{
  String v1 = o1.get("last_name");
  String v2 = o2.get("last_name");
  return (v1 == v2) ? 0 : (v1 == null ? 1 : (v2 == null ? -1 : v1.compareTo(v2))) ;
});

Switch 1 and -1 if you want the null values first or last.如果您想要第一个或最后一个null值,请切换1-1

For thoroughness' sake I've added the generator of useful test cases:为了彻底起见,我添加了有用的测试用例生成器:

Random random = new Random();

random.setSeed(System.currentTimeMillis());

IntStream.range(0, random.nextInt(20)).forEach(i -> {
  Map<String, String> map1 = new HashMap<String, String>();
  String name = new BigInteger(130, new SecureRandom()).toString(6);
  if (random.nextBoolean())
    name = null;
  map1.put("last_name", name);
  peopleList.add(map1);
});

Since your peopleList might contain a null and the Map::key might have a null value, you probably need to nullsLast twice:由于您的peopleList可能包含一个null并且Map::key可能有一个 null 值,您可能需要nullsLast两次:

peopleList.sort(Comparator.nullsLast(Comparator.comparing(m -> m.get("last_name"),
                            Comparator.nullsLast(Comparator.naturalOrder()))));

You can override de compare method of the Collection.您可以覆盖集合的 de compare 方法。 Here is an example: https://www.mkyong.com/java8/java-8-lambda-comparator-example/这是一个例子: https : //www.mkyong.com/java8/java-8-lambda-comparator-example/

You will have to compare the last_name of the objects, and do not forget to handle the null properly.您将不得不比较对象的 last_name,并且不要忘记正确处理空值。

Steps to sort a Map in Java 8.

1]Convert a Map into a Stream
2]Sort it
3]Collect and return a new LinkedHashMap (keep the order)

Map result = map.entrySet().stream()
    .sorted(Map.Entry.comparingByKey())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

Try this:尝试这个:

By Keys:按键:

Map<String, String> result = unsortMap.entrySet().stream()
    .sorted(Map.Entry.comparingByKey())
    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

By Values:按价值观:

 Map<String, String> result = unsortMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM