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

fzsnzjdm  于 2023-06-04  发布在  Java
关注(0)|答案(6)|浏览(209)

如何使用Java 8对Map<String, String>中的List进行排序?Map包含一个名为last_name的键,与之关联的值可能是null。我不知道该怎么做,因为下面的代码会导致编译器错误:

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

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

使用匿名类是唯一的方法吗?
请注意,我不是尝试对列表中的每个Map进行排序。我想根据每个Map中的键对列表本身进行排序。

rkkpypqq

rkkpypqq1#

看起来你可以像这样重写代码

peopleList.sort(
    Comparator.comparing(
        m -> m.get("yourKey"),  //what property should be compared
        Comparator.nullsLast(Comparator.naturalOrder()) //how it should be compared
    )
)
7uzetpgm

7uzetpgm2#

由于您的peopleList可能包含null,而Map::key可能具有null值,因此您可能需要nullsLast两次:

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

cbwuti443#

这应该符合你的要求。

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

如果你想处理空指针,试试这个“老式”的解决方案:

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

如果您希望null值在前或在后,请切换1-1
为了彻底起见,我添加了有用测试用例的生成器:

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

rslzwgfq4#

您可以重写Collection的de compare方法。下面是一个例子:https://www.mkyong.com/java8/java-8-lambda-comparator-example/
您必须比较对象的last_name,并且不要忘记正确处理null。

qv7cva1a

qv7cva1a5#

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

pprl5pva6#

试试这个:
按键:

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

按值:

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

相关问题