Java 8 如何获得多属性';使用java8流的平均值是多少?
有一个物体Java 8 如何获得多属性';使用java8流的平均值是多少?,java-8,java-stream,Java 8,Java Stream,有一个物体 @Data class ScoreInfo{ String id; float cove_score; float theam_score; float content_score; float teach_score; Date create_date; ScoreInfoP scoreInfoP; } ScoreInfoP是: @Data class ScoreInfoP{ String stream_sn; String anchor_id; String crea
@Data
class ScoreInfo{
String id;
float cove_score;
float theam_score;
float content_score;
float teach_score;
Date create_date;
ScoreInfoP scoreInfoP;
}
ScoreInfoP是:
@Data
class ScoreInfoP{
String stream_sn;
String anchor_id;
String create_by;
}
sourceList是ScoreInfo的列表,我想获得cove_分数、theam_分数、content_分数、teach_分数的平均值、group by scoreInfoP属性并为每个属性返回四个平均值
使用这样的代码,我只能得到一个平均值:
Map<ScoreInfoP, Double> meanForCoveScore = sourceList.stream().collect(Collectors.groupingBy(ScoreInfo::getScoreInfoP,
Collectors.averagingDouble(ScoreInfo::getCove_score)));
Map meansforcovescore=sourceList.stream().collect(收集器.groupingBy(ScoreInfo::getScoreInfoP、,
收集器.averagingDouble(ScoreInfo::getCove_score));
我想学习如何使用java8或您建议的任何更简单的方法获得四个平均值
在这里等待您的慷慨帮助。没有任何内置功能,但为其构建自定义收集器并不复杂
Map<String, List<Float>> result = Arrays.asList(first, second)
.stream()
.collect(Collectors.groupingBy(
x -> x.getScoreInfoP().getAnchorId(),
Collector.of(
() -> new float[5],
(a, x) -> {
a[0] += x.getCoveScore();
a[1] += x.getTheamScore();
a[2] += x.getTeachScore();
a[3] += x.getContentScore();
a[4]++;
},
(left, right) -> {
for (int i = 0; i < 4; ++i) {
left[i] += right[i];
}
return left;
}, x -> Arrays.asList(x[0] / x[4], x[1] / x[4], x[2] / x[4], x[3] / x[4]))
));
System.out.println(result);
Map result=Arrays.asList(第一、第二)
.stream()
.collect(收集器.groupingBy(
x->x.getScoreInfoP().getAnchorId(),
收藏(
()->新浮点数[5],
(a,x)->{
a[0]+=x.getCoveScore();
a[1]+=x.gettheamcore();
a[2]+=x.getTeachScore();
a[3]+=x.getContentScore();
a[4]++;
},
(左,右)->{
对于(int i=0;i<4;++i){
左[i]+=右[i];
}
左转;
},x->Arrays.asList(x[0]/x[4],x[1]/x[4],x[2]/x[4],x[3]/x[4]))
));
系统输出打印项次(结果);
实际上,我是在
ScoreInfoP#anchorId
上进行分组的;但您可以在ScoreInfoP
上执行此操作-为此,您需要将x->x.getScoreInfoP().getAnchorId()
更改为x->x.getScoreInfoP()
。但是显然,ScoreInfoP
需要覆盖hashCode
和equals
没有任何内置功能,但是为其构建自定义收集器并不复杂
Map<String, List<Float>> result = Arrays.asList(first, second)
.stream()
.collect(Collectors.groupingBy(
x -> x.getScoreInfoP().getAnchorId(),
Collector.of(
() -> new float[5],
(a, x) -> {
a[0] += x.getCoveScore();
a[1] += x.getTheamScore();
a[2] += x.getTeachScore();
a[3] += x.getContentScore();
a[4]++;
},
(left, right) -> {
for (int i = 0; i < 4; ++i) {
left[i] += right[i];
}
return left;
}, x -> Arrays.asList(x[0] / x[4], x[1] / x[4], x[2] / x[4], x[3] / x[4]))
));
System.out.println(result);
Map result=Arrays.asList(第一、第二)
.stream()
.collect(收集器.groupingBy(
x->x.getScoreInfoP().getAnchorId(),
收藏(
()->新浮点数[5],
(a,x)->{
a[0]+=x.getCoveScore();
a[1]+=x.gettheamcore();
a[2]+=x.getTeachScore();
a[3]+=x.getContentScore();
a[4]++;
},
(左,右)->{
对于(int i=0;i<4;++i){
左[i]+=右[i];
}
左转;
},x->Arrays.asList(x[0]/x[4],x[1]/x[4],x[2]/x[4],x[3]/x[4]))
));
系统输出打印项次(结果);
实际上,我是在
ScoreInfoP#anchorId
上进行分组的;但您可以在ScoreInfoP
上执行此操作-为此,您需要将x->x.getScoreInfoP().getAnchorId()
更改为x->x.getScoreInfoP()
。但是很明显,ScoreInfoP
需要覆盖hashCode
和equals
,正如我在评论中所说的,您应该使用适当的结果类
class ScoreInfoAverage {
private float cove_score;
private float theam_score;
private float content_score;
private float teach_score;
// ctor, getter, setter
}
然后您可以使用自定义的
收集器
:
public static Collector<ScoreInfo, ?, ScoreInfoAverage> scoreInfoToAverage() {
class ScoreInfoAccumulator {
private DoubleSummaryStatistics cove_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics theam_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics content_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics teach_score = new DoubleSummaryStatistics();
public void add(ScoreInfo si) {
cove_score.accept(si.cove_score);
theam_score.accept(si.theam_score);
content_score.accept(si.content_score);
teach_score.accept(si.teach_score);
}
public ScoreInfoAccumulator combine(ScoreInfoAccumulator sia) {
cove_score.combine(sia.cove_score);
theam_score.combine(sia.theam_score);
content_score.combine(sia.content_score);
teach_score.combine(sia.teach_score);
return this;
}
public ScoreInfoAverage average() {
return new ScoreInfoAverage((float) cove_score.getAverage(),
(float) theam_score.getAverage(), (float) content_score.getAverage(),
(float) teach_score.getAverage());
}
}
return Collector.of(ScoreInfoAccumulator::new, ScoreInfoAccumulator::add,
ScoreInfoAccumulator::combine, ScoreInfoAccumulator::average);
}
正如我在评论中所说的,您应该使用适当的结果类
class ScoreInfoAverage {
private float cove_score;
private float theam_score;
private float content_score;
private float teach_score;
// ctor, getter, setter
}
然后您可以使用自定义的
收集器
:
public static Collector<ScoreInfo, ?, ScoreInfoAverage> scoreInfoToAverage() {
class ScoreInfoAccumulator {
private DoubleSummaryStatistics cove_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics theam_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics content_score = new DoubleSummaryStatistics();
private DoubleSummaryStatistics teach_score = new DoubleSummaryStatistics();
public void add(ScoreInfo si) {
cove_score.accept(si.cove_score);
theam_score.accept(si.theam_score);
content_score.accept(si.content_score);
teach_score.accept(si.teach_score);
}
public ScoreInfoAccumulator combine(ScoreInfoAccumulator sia) {
cove_score.combine(sia.cove_score);
theam_score.combine(sia.theam_score);
content_score.combine(sia.content_score);
teach_score.combine(sia.teach_score);
return this;
}
public ScoreInfoAverage average() {
return new ScoreInfoAverage((float) cove_score.getAverage(),
(float) theam_score.getAverage(), (float) content_score.getAverage(),
(float) teach_score.getAverage());
}
}
return Collector.of(ScoreInfoAccumulator::new, ScoreInfoAccumulator::add,
ScoreInfoAccumulator::combine, ScoreInfoAccumulator::average);
}
你的意思是得到每个平均值吗?最优雅的方法是创建一个结果类。@holi java是的,我想得到四个平均值values@Flown我可以详细地问你怎么做吗..但是4个平均值的类型不是
Map
,它应该是Map
。你的意思是获取每个平均值吗?最优雅的方法是创建一个结果类。@holi java是的,我想获取四个平均值values@Flown我可以详细地问你怎么做吗..但是4个平均值的类型不是Map
,它应该是Map
。我觉得有点太多了。。。你可以简单地把它们加起来,然后再分;与普通的收集器几乎相同。平均值…
does@Eugene为什么要一次又一次地重新发明轮子?我不理解你的评论honest@Eugene你指的是双重总和统计,对吧?那么,既然JDK中已经有了经过测试的功能,我为什么还要在以后添加和划分呢?哦,对了——这对我的口味来说可能太多了,而且我觉得可读性较差——但这里可能是我。另外,你也有一个观点(不确定你是否知道)-你的解决方案使用了Kahan求和,它比简单的加法/除法做得更好。。。你可以简单地把它们加起来,然后再分;与普通的收集器几乎相同。平均值…
does@Eugene为什么要一次又一次地重新发明轮子?我不理解你的评论honest@Eugene你指的是双重总和统计,对吧?那么,既然JDK中已经有了经过测试的功能,我为什么还要在以后添加和划分呢?哦,对了——这对我的口味来说可能太多了,而且我觉得可读性较差——但这里可能是我。另外,这里也有一点(不确定您是否知道)-您的解决方案使用Kahan求和,比简单的加法/除法更能进行舍入。我使用Lombok,带有数据注释,不需要提供hashcode和equals。我用你的模板修改了我的代码,它失败了。但我认为你的清晰方法是正确的,我需要学习它并找出它失败的原因。它现在编译成功了。现在我没有数据要测试,我没有