猿问

Java 8 中超过 2 个 groupingBy 操作

这是我的“revenue_data.csv”文件:


Client  ReportDate  Revenue

C1      2019-1-7    12

C2      2019-1-7    34

C1      2019-1-16   56

C2      2019-1-16   78

C3      2019-1-16   90

我读取文件的案例类是:


package com.source.code;


import java.time.LocalDate;


public class RevenueRecorder {


    private String clientCode;

    private LocalDate reportDate;

    private int revenue;



    public RevenueRecorder(String clientCode, LocalDate reportDate, int revenue) {

        this.clientCode = clientCode;

        this.reportDate = reportDate;

        this.revenue = revenue;

    }


    public String getClientCode() {

        return clientCode;

    }


    public LocalDate getReportDate() {

        return reportDate;

    }


    public int getRevenue() {

        return revenue;

    }

}

我可以按以下方式读取文件并按 ReportDate、sum(revenue) 进行分组:


import com.source.code.RevenueRecorder;


import java.io.IOException;

import java.nio.file.FileSystems;

import java.nio.file.Files;

import java.nio.file.Path;

import java.time.LocalDate;

import java.time.format.DateTimeFormatter;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;


import static java.util.stream.Collectors.groupingBy;

import static java.util.stream.Collectors.summingInt;


public class RevenueRecorderMain {


    public static void main(String[] args) throws IOException {


        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");

        List<RevenueRecorder> revenueRecords = new ArrayList<>();


        Path path = FileSystems.getDefault().getPath("src", "main", "resources",

                "data", "revenue_data.csv");


        Files.lines(path)

                .skip(1)

                .map(s -> s.split(","))

                .forEach(s ->


我的问题是如何在 Java 8 中按 ReportDate、count(clientCode) 和 sum(revenue) 进行分组,具体来说:


使用什么集合来代替 Map

在这种情况下如何进行分组和收集(通常对于超过 2 个分组)


慕田峪7331174
浏览 213回答 3
3回答

子衿沉夜

虽然你的尝试没有成功,但我觉得是你最想表达的。所以我只是按照你的代码并修复它。试试这个!Map<LocalDate, ImmutablePair<Integer, Map<String, Long>>> map = revenueRecords.stream()             .collect(groupingBy(RevenueRecorder::getReportDate,                     collectingAndThen(toList(), list -> new ImmutablePair(list.stream().collect(summingInt(RevenueRecorder::getRevenue)),                                                                           list.stream().collect(groupingBy(RevenueRecorder::getClientCode, Collectors.counting()))))));结果如下这是我自己的想法,希望能帮到你。╰( ̄▽ ̄)╭

慕妹3146593

如果您已经使用 Java 12,则有一个新的收集器Collectors.teeing(),它允许使用两个独立的收集器进行收集,然后使用提供的 BiFunction 合并它们的结果。传递到结果收集器的每个元素都由两个下游收集器处理,然后使用指定的合并函数将它们的结果合并到最终结果中。因此Collectors.teeing()可能很适合,因为您想要计数和求和。Map<LocalDate, Result> pairedReportDateMRR =&nbsp;&nbsp; &nbsp; revenueRecords.stream().collect(Collectors.groupingBy(RevenueRecorder::getReportDate,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collectors.teeing(Collectors.counting(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collectors.summingInt(RevenueRecorder::getRevenue), Result::new)));&nbsp; &nbsp; System.out.println(pairedReportDateMRR);&nbsp;&nbsp; &nbsp;//output: {2019-01-07={count=2, sum=46}, 2019-01-16={count=3, sum=224}}出于测试目的,我使用了以下简单的静态类static class Result {&nbsp; &nbsp; private Long count;&nbsp; &nbsp; private Integer sum;&nbsp; &nbsp; public Result(Long count, Integer sum) {&nbsp; &nbsp; &nbsp; &nbsp; this.count = count;&nbsp; &nbsp; &nbsp; &nbsp; this.sum = sum;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public String toString() {&nbsp; &nbsp; &nbsp; &nbsp; return "{" + "count=" + count + ", sum=" + sum + '}';&nbsp; &nbsp; }}

素胚勾勒不出你

首先,Map<LocalDate, Pair<Integer, Integer>>由于您想进行第二次分组,您无法制作地图,这意味着对于同一日期,您可能有多个客户代码,每个客户代码都有单独的计数器。所以如果我没猜错你就不会得到这样的东西Map<LocalDate, MutablePair<Integer, Map<String, Integer>>>,如果它是正确的试试这个代码片段:public static void main(String[] args) {&nbsp; &nbsp; String data = "C1,2019-1-7,12\n" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "C2,2019-1-7,34\n" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "C1,2019-1-16,56\n" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "C2,2019-1-16,78\n" +&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "C3,2019-1-16,90";&nbsp; &nbsp; Stream.of(data.split("\n")).forEach(System.out::println);&nbsp; &nbsp; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");&nbsp; &nbsp; List<RevenueRecorder> revenueRecords = Stream.of(data.split("\n")).map(line -> {&nbsp; &nbsp; &nbsp; &nbsp; String[] s = line.split(",");&nbsp; &nbsp; &nbsp; &nbsp; String clientCode = s[0];&nbsp; &nbsp; &nbsp; &nbsp; LocalDate reportDate = LocalDate.parse(s[1].trim(), formatter);&nbsp; &nbsp; &nbsp; &nbsp; int revenue = Integer.parseInt(s[2]);&nbsp; &nbsp; &nbsp; &nbsp; return new RevenueRecorder(clientCode, reportDate, revenue);&nbsp; &nbsp; }).collect(toList());&nbsp; &nbsp; Supplier<MutablePair<Integer, Map<String, Integer>>> supplier = () -> MutablePair.of(0, new HashMap<>());&nbsp; &nbsp; BiConsumer<MutablePair<Integer, Map<String, Integer>>, RevenueRecorder> accumulator = (pair, recorder) -> {&nbsp; &nbsp; &nbsp; &nbsp; pair.setLeft(pair.getLeft() + recorder.getRevenue());&nbsp; &nbsp; &nbsp; &nbsp; pair.getRight().merge(recorder.getClientCode(), 1, Integer::sum);&nbsp; &nbsp; };&nbsp; &nbsp; BinaryOperator<MutablePair<Integer, Map<String, Integer>>> combiner = (p1, p2) -> {&nbsp; &nbsp; &nbsp; &nbsp; p1.setLeft(p1.getLeft() + p2.getLeft());&nbsp; &nbsp; &nbsp; &nbsp; p2.getRight().forEach((key, val) -> p1.getRight().merge(key, val, Integer::sum));&nbsp; &nbsp; &nbsp; &nbsp; return p1;&nbsp; &nbsp; };&nbsp; &nbsp; Map<LocalDate, MutablePair<Integer, Map<String, Integer>>> pairedReportDateMRR = revenueRecords.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; groupingBy(RevenueRecorder::getReportDate,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Collector.of(supplier, accumulator, combiner))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; System.out.println(pairedReportDateMRR);}
随时随地看视频慕课网APP

相关分类

Java
我要回答