【问题标题】:Java 8 Stream - Map - sort by value [duplicate]Java 8 Stream - Map - 按值排序[重复]
【发布时间】:2018-05-18 14:49:50
【问题描述】:

这是我的数据集。

public class StudentData {

    public static List<Student> getData() {
        //student id,name,std, and hobbies
        return Arrays.asList(new Student(1, "a1", 1, Arrays.asList("cricket", "football", "basketball")),
                new Student(2, "a2", 1, Arrays.asList("chess", "football")),
                new Student(3, "a3", 2, Arrays.asList("running")),
                new Student(4, "a4", 2, Arrays.asList("throwball", "football")),
                new Student(5, "a5", 3, Arrays.asList("cricket", "basketball")),
                new Student(6, "a6", 4, Arrays.asList("cricket")), new Student(7, "a7", 5, Arrays.asList("basketball")),
                new Student(8, "a8", 6, Arrays.asList("football")),
                new Student(9, "a9", 8, Arrays.asList("tennis", "swimming")),
                new Student(10, "a10", 8, Arrays.asList("boxing", "running")),
                new Student(11, "a11", 9, Arrays.asList("cricket", "football")),
                new Student(12, "a12", 11, Arrays.asList("tennis", "shuttle")),
                new Student(13, "a13", 12, Arrays.asList("swimming")));
    }

}

从数据集中,我发现有多少学生基于爱好并以 asc/desc 顺序显示值。例如:板球、4 和游泳:2 等等。
这是按啤酒花分组的代码。

Map<String, Integer> collect8 = data.stream()
                .flatMap(x -> x.getHobbies().stream().map(y -> new SimpleEntry<>(y, x)))
                .collect(Collectors.groupingBy(Entry::getKey, Collectors.mapping(entry -> entry.getValue().getId(),
                        Collectors.reducing(0, (a, b) -> a + b))));

collect8 的输出:{跑步=13,游泳=22,穿梭=12,投掷球=4,篮球=13,国际象棋=2,板球=23,拳击=10,足球=26,网球=21}

之后我按值进行 asc 排序。

Map<String, Integer> collect9 = 
                collect8.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue()).
                collect(Collectors.toMap(e->e.getKey(), e->e.getValue()));
        System.out.println(collect9);

collect9 的输出:{跑步=2,游泳=2,穿梭=1,投掷=1,篮球=3,国际象棋=1,板球=4,拳击=1,足球=5,网球=2}

1.它没有排序并给出相同的结果。知道吗?
2. 我正在编写单独的代码进行排序。可以在collect8本身做吗?

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    对于第一个问题,Collectors.toMap() 当前创建了一个HashMap,它没有排序,因此对Stream 进行排序对最终的Map 没有影响。如果您改为创建LinkedHashMap,它将保留插入顺序。

    Map<String, Integer> collect9 = 
                    collect8.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue()).
                    collect(Collectors.toMap(e->e.getKey(), e->e.getValue(),(v1,v2)->v2,LinkedHashMap::new));
    

    至于在单个管道中进行分组和排序,我不知道有什么方法可以实现。如果排序是通过Map 的键完成的,您可以通过在第一个Streamcollect 中生成TreeMap 来轻松实现它,但是由于您想按值排序,我可以在单个 Stream 管道中看不到这样做的方法。

    【讨论】:

    • 非常感谢.. 工作正常。 (v1,v2)-> v1 - 不是什么意思。它也尝试过-> v2。它给出了相同的输出。为什么是 v1、v2?
    • @LearnHadoop 这是一个组合器函数,如果您想使用指定所需Map 实现的变体,则必须将其传递给toMap 收集器。我随意选择了(v1,v2)->v1,这意味着如果收集器遇到重复的键,它会将为该键找到的第一个值分配给该键。如果没有重复的键,(v1,v2)->v2 的行为完全相同。
    猜你喜欢
    • 2021-08-19
    • 2018-09-08
    • 1970-01-01
    • 2021-03-01
    • 2016-08-23
    • 2017-02-18
    • 2012-11-30
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多