gpt4 book ai didi

java - 结合两个流 Java 8

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

有没有办法合并以下两个语句?

    Map<Integer,Double> collX = listeAllerPunkte.stream().collect(groupingBy(DataPoint::getId,
averagingDouble(DataPoint::getX)));
Map<Integer,Double> collY = listeAllerPunkte.stream().collect(groupingBy(DataPoint::getId,
averagingDouble(DataPoint::getY)));

我有一个像这样的 DataPoints 类:

public class DataPoint {

public final double x;
public final double y;
private int Id;

public DataPoint(double x, double y) {
this.x = x;
this.y = y;
}

public double getX() {
return x;
}

public double getY() {
return y;
}

public int getId() {
return Id;
}
}

Id 包含一个介于 0-5 之间的随机值。

listeAllerPunkte 是一个包含很多DataPoints

List

现在我想为列表中具有相同 Id 的每个 DataPoints 创建一个 DataPointDataPoint 应具有具有相同 Id 的数据点的 x 和 y 值 的平均值。

对于开头的两个 Statemante,我必须从两个 map 中手动创建 DataPoints。有没有办法直接在流中创建它们?

最佳答案

一个通用的解决方案是使用一个收集器,它可以组合两个收集器来同时处理这两个收集器。不幸的是,标准 API 中不存在这样的收集器,但是 this answer提供此类收集器的实现。

或者,您可以通过创建自己的类来保存要点的摘要,从而为这种特定情况创建解决方案,例如

static class DataPointSummary {
long count;
double sumX, sumY;

public double getAverageX() {
return count==0? 0: sumX/count;
}
public double getAverageY() {
return count==0? 0: sumY/count;
}
public void add(DataPoint p) {
count++;
sumX+=p.getX();
sumY+=p.getY();
}
public DataPointSummary merge(DataPointSummary s) {
count+=s.count;
sumX+=s.sumX;
sumY+=s.sumY;
return this;
}
@Override
public String toString() {
return "DataPointSummary["+count+" points"
+", avg x="+getAverageX()+", avg y="+getAverageY()+']';
}
}

然后你可以像这样收集你的积分

Map<Integer,DataPointSummary> coll = listeAllerPunkte.stream().collect(
groupingBy(DataPoint::getId, Collector.of(
DataPointSummary::new, DataPointSummary::add, DataPointSummary::merge)));

请注意,我假设您的方法签名 public double getId() 是一个拼写错误,实际上 public int getId() 否则,您问题中的示例将不会不工作。

如果点的坐标具有相同的大小,则上面的摘要实现效果很好。如果您在同一组中同时遇到非常大的值和非常小的值,您可能需要一个带误差补偿算法的求和。我建议不要自己实现,而是使用 JRE 的摘要实现:

static class DataPointSummary {
final DoubleSummaryStatistics x=new DoubleSummaryStatistics();
final DoubleSummaryStatistics y=new DoubleSummaryStatistics();

public double getAverageX() {
return x.getAverage();
}
public double getAverageY() {
return y.getAverage();
}
public void add(DataPoint p) {
x.accept(p.getX());
y.accept(p.getY());
}
public DataPointSummary merge(DataPointSummary s) {
x.combine(s.x);
y.combine(s.y);
return this;
}
@Override
public String toString() {
return "DataPointSummary["+x.getCount()+" points"
+", avg x="+getAverageX()+", avg y="+getAverageY()+']';
}
}

此变体的使用方式与第一个变体相同。

关于java - 结合两个流 Java 8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33824995/

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