You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将按Type分组的Map<Type,List<String>>按值排序存入LinkedHashMap

解决Map按List值排序的编译错误

问题背景

定义了如下Item类和菜单列表:

@AllArgsConstructor
@Getter
public static class Item {
    public enum Type { Meat, Fish }

    private String name;
    private int price;
    private Type type;
}
List<Item> menu = Arrays.asList(
    new Item("pork", 800, Item.Type.Meat), 
    new Item("beef", 700, Item.Type.Meat), 
    new Item("chicken", 200, Item.Type.Meat), 
    new Item("prawns", 300, Item.Type.Fish),
    new Item("salmon", 450, Item.Type.Fish)
);

需求是将Item按Type分组存入Map,再将该Map的条目按值(List<String>类型)升序排序后存入LinkedHashMap,但尝试的代码出现编译错误:

Type parameter 'java.util.List' is not within its bound;
should extend 'java.lang.Comparable<? super java.util.List>'

错误原因

Map.Entry.comparingByValue()默认要求值类型实现Comparable接口,而List<String>并没有实现该接口(虽然String是Comparable,但容器本身不是),所以无法直接使用默认的比较方法。

解决方案

需要为List<String>自定义比较逻辑,以下是两种常见实现方式:

方式1:按List的元素数量排序

如果需求是按分组后列表的大小升序排序,可直接基于列表长度构建比较器:

// 按Type分组
Map<Item.Type, List<String>> map = menu.stream()
    .collect(Collectors.groupingBy(
        Item::getType,
        Collectors.mapping(Item::getName, Collectors.toList())
    ));

// 按List大小升序排序并存入LinkedHashMap
Map<Item.Type, List<String>> sortedMap = map.entrySet().stream()
    .sorted(Map.Entry.comparingByValue(Comparator.comparingInt(List::size)))
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (oldVal, newVal) -> oldVal,
        LinkedHashMap::new
    ));

方式2:按List中元素的字典序排序

如果需要按列表内元素的自然顺序(字典序)逐个比较排序,可自定义列表比较逻辑:

// 按Type分组
Map<Item.Type, List<String>> map = menu.stream()
    .collect(Collectors.groupingBy(
        Item::getType,
        Collectors.mapping(Item::getName, Collectors.toList())
    ));

// 自定义List<String>比较器:逐个元素比较,长度短的在前
Comparator<List<String>> listComparator = (list1, list2) -> {
    int minSize = Math.min(list1.size(), list2.size());
    for (int i = 0; i < minSize; i++) {
        int cmp = list1.get(i).compareTo(list2.get(i));
        if (cmp != 0) {
            return cmp;
        }
    }
    return Integer.compare(list1.size(), list2.size());
};

// 按自定义逻辑排序并存入LinkedHashMap
Map<Item.Type, List<String>> sortedMap = map.entrySet().stream()
    .sorted(Map.Entry.comparingByValue(listComparator))
    .collect(Collectors.toMap(
        Map.Entry::getKey,
        Map.Entry::getValue,
        (oldVal, newVal) -> oldVal,
        LinkedHashMap::new
    ));

优化点说明

  • 直接使用Collectors.toMap()结合LinkedHashMap构造器,替代手动创建LinkedHashMap再forEachOrdered的方式,代码更简洁且符合流式编程习惯。
  • 自定义比较器时,需明确排序规则(长度、元素顺序等),根据实际业务需求选择合适的逻辑。

内容的提问来源于stack exchange,提问作者Mark Skylarkxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:05:29