当前位置: 首页 > 知识库问答 >
问题:

使用流API为列表中的每个对象计算对象值的累积和

杨慎之
2023-03-14

我试图实现列表中对象值的累积和。

对象如下所示:

public class NameValuePair {
    private String name;
    private int value;
}

我有一份清单

结果也应该是一个列表

如何使用Java流API实现它?

输入示例为:

("a", 2), ("b", 12), ("c", 15), ("d", 20)

所需输出为:

("a", 2), ("b", 14), ("c", 29), ("d", 49)

共有2个答案

荀辰钊
2023-03-14

可以在收集器内处理累积值的过程。

在这种情况下,不需要将当前值存储在流管道之外并通过副作用进行更新,API文档不鼓励这样做。

为此,我们需要定义一个自定义收集器。它可以实现为实现Collector接口的类,或者我们可以使用静态方法Collector.of()

这些是收集器预期的参数。of():

>

累加器<代码>Bi消费者

组合器<代码>二进制运算符

分页装订器功能

特性允许提供附加信息,例如收集器。特点。本例中使用的无序表示并行执行时产生的部分缩减结果的顺序不显著。此收集器不需要任何特性。

public static List<NameValuePair> accumulateValues(List<NameValuePair> pairs) {
    return pairs.stream()
        .collect(getPairAccumulator());
}

public static Collector<NameValuePair, ?, List<NameValuePair>> getPairAccumulator() {
    
    return Collector.of(
        ArrayDeque::new, // mutable container
        (Deque<NameValuePair> deque, NameValuePair pair) -> {
            if (deque.isEmpty()) deque.add(pair);
            else deque.add(new NameValuePair(pair.name(), deque.getLast().value() + pair.value()));
        },
        (left, right) -> { throw new AssertionError("should not be executed in parallel"); }, // combiner - function responsible 
        (Deque<NameValuePair> deque) -> deque.stream().toList() // finisher function
    );
}

如果您使用的是Java 16或更高版本,则可以将NameValuePair实现为记录:

public record NameValuePair(String name, int value) {}

<代码>main()

public static void main(String[] args) {
    List<NameValuePair> pairs =
        List.of(new NameValuePair("a", 2), new NameValuePair("b", 12),
                new NameValuePair("c", 15), new NameValuePair("d", 20));

    List<NameValuePair> result = accumulateValues(pairs);
    result.forEach(System.out::println);
}

输出:

NameValuePair[name=a, value=2]
NameValuePair[name=b, value=14]
NameValuePair[name=c, value=29]
NameValuePair[name=d, value=49]

在线演示的链接

壤驷俊逸
2023-03-14

可以使用AtomicInteger存储累积值:

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


....


List<NameValuePair> list = List.of( new NameValuePair("a", 2),
                                    new NameValuePair("b", 12),
                                    new NameValuePair("c", 15),
                                    new NameValuePair("d", 20));

AtomicInteger ai = new AtomicInteger(0);

List<NameValuePair> result = list.stream()
                                 .map(nvp -> new NameValuePair(nvp.getName(), ai.addAndGet(nvp.getValue())))
                                 .collect(Collectors.toList());
 类似资料:
  • 我有以下列表: 我需要计算累计总和-列表含义 我想使用Java流API进行计算,以便我可以使用Spark实现它以进行大数据计算。我在JavaStreams中很天真,我尝试了几个表达式,但没有一个是有效的,等效的结构代码应该是这样的:

  • 我有一个按月-年字符串属性排序的对象列表。我的对象类定义如下 我想对会员人数、非会员人数、会员付款、非会员付款进行累计和 所以我的新对象列表如下 我尝试与但它给我所有的总和不累积。 非常感谢任何指点。

  • 问题内容: 我试图弄清楚如何将累积函数应用于对象。对于数字,有多种选择,例如和。还有df.expanding可以与一起使用。但是我传递给我的功能不适用于对象。 在数据框中,我具有整数值,集合,字符串和列表。现在,如果我尝试一下,我有累加的总和: 我的期望是,由于求和是在列表和字符串上定义的,所以我会得到如下信息: 我也尝试过这样的事情: 它按我的预期工作:以前的结果是,当前行的值是。但是例如,我不

  • 我正在尝试为我的列表模式中的每个对象创建一个包含该对象数据的表单。 所以我的控制器中有: 在我的ThymeLeaf模板中: 控制器: ThymeLeaf模板: 这种情况不会引发任何异常,但为空

  • 为所有的代码道歉。我尽量少发帖。

  • 我正在尝试对List的字段求和并返回值。我想为此使用流,但我对流不熟悉,不确定流是否可以完成此操作。这是我尝试过的,但我认为语法不正确。 上下文的相关类结构。 获取总价和单价方法