gpt4 book ai didi

java - 如何使用 Java 流计算两个聚合函数?

转载 作者:搜寻专家 更新时间:2023-11-01 03:22:06 25 4
gpt4 key购买 nike

我有一个这样的“请求”对象列表(id、数量、价格)

List<Request> requests = Arrays.asList(
new Request(id++, 20, 59.28),
new Request(id++, 10, 61.23),
new Request(id++, 30, 60.67),
new Request(id++, 25, 60.16),
new Request(id++, 60, 59.67));

我想在一次迭代中计算两个指标 - sum(amount) 和 sum(amount * price)。我需要他们计算平均价格:sum(amount * price)/sum(amount)。

考虑到我想使用 Java 8 流,我发现的唯一变体是将值映射到 Pair 对象并实现自定义消费者:

static class Aggregate implements Consumer<Pair<Double, Double>> {
private double count = 0L;
private double sum = 0L;

public double average() {
return count > 0 ? sum/(double) count : 0;
}

public void combine(Aggregate other) {
count += other.count;
sum += other.sum;
}

@Override
public void accept(Pair<Double, Double> data) {
this.count += data.getLeft();
this.sum += data.getLeft() * data.getRight();
}
}

Double avgPrice = requests.stream()
.map(e -> Pair.<Double, Double>of(e.getAmount(), e.getPrice()))
.collect(Aggregate::new, Aggregate::accept, Aggregate::combine)
.average();

这种方法看起来很困惑——我们必须为每个条目创建额外的 Pair 对象 :(

有人知道更好的解决方案吗?

最佳答案

当然。您将需要自定义聚合,但不需要 Pair:

 static class Aggregate {
private long count = 0L;
private double sum = 0L;
double average() { return sum / count; }
void merge(Aggregate other) {
count += other.count;
sum += other.sum;
}
void add(int count, double value) {
this.count += count;
this.sum += count * value;
}
}
}

requests.stream().collect(
Aggregate::new,
(aggr, request) -> aggr.add(request.getCount(), request.getPrice()),
Aggregate::merge)
.average();

而且您实际上不需要实现 Consumer

老实说,多遍解决方案可能几乎一样快,也简单得多......

requests.stream()
.mapToDouble(request -> request.getCount() * request.getPrice())
.sum()
/ requests.stream().mapToLong(Request::getCount).sum();

关于java - 如何使用 Java 流计算两个聚合函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27720601/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com