如何在 Java 8 流中应用 groupby->mapping->reducing
How to apply groupby->mapping->reducing in Java 8 stream
我有以下对象的列表。
public class Sample {
private String driver;
private String vehicle;
private Double score;
private Integer time;
}
我的数据如下所示。
我正在尝试 groupBy driver 然后应用 map 函数(在上面 table 中提到)然后减少到 Map with key as driver 和 value 作为 map 函数的结果(类型为 Double)。
我试过下面
list.stream().collect(Collectors.groupingBy(o-> o.getDriverId(),
Collectors.mapping()
));
但是无法应用地图功能。请提供一些意见以继续进行。
希望这对您的问题陈述有所帮助。
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
List<Sample> data = Arrays.asList(
new Sample("D1","V1",1.0,10),
new Sample("D1","V2",2.0,20),
new Sample("D2","V3",3.0,30),
new Sample("D2","V4",4.0,40));
Map<String,Double> calculatedDataMapping = new HashMap<>();
data.stream().collect(Collectors.groupingBy(Sample::getDriver)).forEach((k,v) -> {
double value = 0.0;
for(int i = 0 ; i < v.size()-1; i++){
value = ((v.get(i).getScore() * v.get(i).getTime()) + (v.get(i+1).getScore() * v.get(i+1).getTime()))
/ (v.get(i).getTime() + v.get(i + 1).getTime());
}
calculatedDataMapping.put(k,value);
});
System.out.println(calculatedDataMapping);
}
}
Sample.java
public class Sample {
private String driver;
private String vehicle;
private Double score;
private Integer time;
public Sample(String driver, String vehicle, Double score, Integer time) {
this.driver = driver;
this.vehicle = vehicle;
this.score = score;
this.time = time;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getVehicle() {
return vehicle;
}
public void setVehicle(String vehicle) {
this.vehicle = vehicle;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public Integer getTime() {
return time;
}
public void setTime(Integer time) {
this.time = time;
}
@Override
public String toString() {
return "Sample{" +
"driver='" + driver + '\'' +
", vehicle='" + vehicle + '\'' +
", score=" + score +
", time=" + time +
'}';
}
}
输出
{D1=1.6666666666666667, D2=3.5714285714285716}
谢谢
格达尔
试试这个:
Map<String, Double> res =
list.stream()
.collect(groupingBy(Sample::getDriver,
collectingAndThen(
reducing(new Sample("", "", 0.0,0),
(a, b) -> new Sample("", "", a.score + b.score * b.time, a.time + b.time)),
s -> s.score / s.time)));
我有以下对象的列表。
public class Sample {
private String driver;
private String vehicle;
private Double score;
private Integer time;
}
我的数据如下所示。
我正在尝试 groupBy driver 然后应用 map 函数(在上面 table 中提到)然后减少到 Map with key as driver 和 value 作为 map 函数的结果(类型为 Double)。 我试过下面
list.stream().collect(Collectors.groupingBy(o-> o.getDriverId(),
Collectors.mapping()
));
但是无法应用地图功能。请提供一些意见以继续进行。
希望这对您的问题陈述有所帮助。
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
List<Sample> data = Arrays.asList(
new Sample("D1","V1",1.0,10),
new Sample("D1","V2",2.0,20),
new Sample("D2","V3",3.0,30),
new Sample("D2","V4",4.0,40));
Map<String,Double> calculatedDataMapping = new HashMap<>();
data.stream().collect(Collectors.groupingBy(Sample::getDriver)).forEach((k,v) -> {
double value = 0.0;
for(int i = 0 ; i < v.size()-1; i++){
value = ((v.get(i).getScore() * v.get(i).getTime()) + (v.get(i+1).getScore() * v.get(i+1).getTime()))
/ (v.get(i).getTime() + v.get(i + 1).getTime());
}
calculatedDataMapping.put(k,value);
});
System.out.println(calculatedDataMapping);
}
}
Sample.java
public class Sample {
private String driver;
private String vehicle;
private Double score;
private Integer time;
public Sample(String driver, String vehicle, Double score, Integer time) {
this.driver = driver;
this.vehicle = vehicle;
this.score = score;
this.time = time;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getVehicle() {
return vehicle;
}
public void setVehicle(String vehicle) {
this.vehicle = vehicle;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public Integer getTime() {
return time;
}
public void setTime(Integer time) {
this.time = time;
}
@Override
public String toString() {
return "Sample{" +
"driver='" + driver + '\'' +
", vehicle='" + vehicle + '\'' +
", score=" + score +
", time=" + time +
'}';
}
}
输出
{D1=1.6666666666666667, D2=3.5714285714285716}
谢谢 格达尔
试试这个:
Map<String, Double> res =
list.stream()
.collect(groupingBy(Sample::getDriver,
collectingAndThen(
reducing(new Sample("", "", 0.0,0),
(a, b) -> new Sample("", "", a.score + b.score * b.time, a.time + b.time)),
s -> s.score / s.time)));