为了账号安全,请及时绑定邮箱和手机立即绑定

Java Lambda Stream group By和求和整数值/平均值

Java Lambda Stream group By和求和整数值/平均值

撒科打诨 2022-05-25 16:39:21
我有一个客户对象列表(客户:int id,bool isActive,int billingCount,...)并且想要 billingCount 的总和和平均值。不幸的是,我的代码不起作用。我需要如何更改代码才能正常工作?sum 和 average sould 看起来像这样:真1234假 1234 Map<Boolean, Integer> sum = customer.stream()                .map(c -> c.getIsActive())                .collect(Collectors.groupingBy(c -> c, Collectors.summingInt(Customer::getBillingCount)));Map<Boolean, Integer> average = customer.stream()                .map(c -> c.getIsActive())                .collect(Collectors.groupingBy(c -> c, Collectors.averagingInt(Customer::getBillingCount)));    }我收到以下错误:Error:(146, 17) java: no suitable method found for collect(java.util.stream.Collector<Customer,capture#1 of ?,java.util.Map<java.lang.Object,java.lang.Integer>>)    method java.util.stream.Stream.<R>collect(java.util.function.Supplier<R>,java.util.function.BiConsumer<R,? super java.lang.Boolean>,java.util.function.BiConsumer<R,R>) is not applicable      (cannot infer type-variable(s) R        (actual and formal argument lists differ in length))    method java.util.stream.Stream.<R,A>collect(java.util.stream.Collector<? super java.lang.Boolean,A,R>) is not applicable      (inference variable T has incompatible bounds        lower bounds: java.lang.Object,Customer        lower bounds: java.lang.Boolean)
查看完整描述

3 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

通过您的map电话,您正在将您转换Stream<Customer>Stream<Boolean>关于您的活跃和非活跃客户的正确和错误的流。您不能getBillingCount在布尔值上调用 Customer's。

您可以使用收集partitioningBy按布尔值进行分组,而无需事先map调用。下游收集器可以是同时收集总和和平均值的summarizingInt收集器(加上一些您可能不需要的其他收集器:计数、最大值、最小值)。

Map<Boolean, Integer> stats = customer.stream()
    .collect(Collectors.partitioningBy(Customer::getIsActive,
                                       Collectors.summarizingInt(Customer::getBillingCount)));

这应该让您在一个声明中true获得统计数据。false


查看完整回答
反对 回复 2022-05-25
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

您不需要使用map. 请参见下面的示例:


List<Customer> customers = Arrays.asList(

        new Customer(10, true, 5),

        new Customer(11, true, 3),

        new Customer(20, false, 12),

        new Customer(21, false, 11));


Map<Boolean, Integer> sum = customers

        .stream()

        .collect(Collectors.groupingBy(Customer::isActive, Collectors.summingInt(Customer::getBillingCount)));

System.out.println(sum);


Map<Boolean, Double> avg = customers

        .stream()

        .collect(Collectors.groupingBy(Customer::isActive, Collectors.averagingInt(Customer::getBillingCount)));

System.out.println(avg);

上面的代码打印:


{false=23, true=8}

{false=11.5, true=4.0}


查看完整回答
反对 回复 2022-05-25
?
婷婷同学_

TA贡献1844条经验 获得超8个赞

你真的需要一张活跃和不活跃的地图吗?简单地说:


IntSummaryStatistics summaryActive = customer.stream()

        .filter(Customer::getIsActive)

        .mapToInt(Customer::getBillingCount)

        .summaryStatistics();


long sumActive  = summary.getSum();

double averageActive = summary.getAverage();

您可以通过将过滤器替换为非活动来执行相同的操作.filter(c -> !c.getIsActive())


查看完整回答
反对 回复 2022-05-25
  • 3 回答
  • 0 关注
  • 619 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信