我有一个名为Name | 1 | 2 ... | 11 | ... | 19
Man-- | .............. | 1000
Agu-- | ............................| 5000
的数据结构,其中包含名为MyPojo
,time
和name
的字段(所有字符都在字符串中)。我尝试按如下方式进行分组:
timetaken
请注意,我使用了 List<MyPojo> myPojos = Arrays.asList(
new MyPojo("2017", "ABC", "30"),
new MyPojo("2017", "ABC", "20"),
new MyPojo("2016", "ABC", "25"),
new MyPojo("2017", "XYZ", "40")
);
Map<String, Map<String, Double>> resultMap = myPojos.stream()
.collect(Collectors.groupingBy(MyPojo::getName,
Collectors.groupingBy(MyPojo::getTime,
Collectors.averagingDouble(MyPojo::getTimeTakenAsDouble))));
方法将getTimeTakenAsDouble
字符串转换为double值。
结果如下:
timetaken
但是,我的前端开发人员希望数据采用以下格式:
{ABC={2017=25.0, 2016=25.0}, XYZ={2017=40.0}}
或
{ABC={2017=25.0, 2016=25.0}, XYZ={2017=40.0, 2016=0.0}}
我正在考虑对 [
{
"time": "2017",
"name": "ABC",
"avgTimeTaken": 25.0
},
{
"time": "2017",
"name": "XYZ",
"avgTimeTaken": 40.0
},
{
"time": "2016",
"name": "ABC",
"avgTimeTaken": 25.0
},
{
"time": "2016",
"name": "XYZ",
"avgTimeTaken": 0.0
}
]
执行迭代并准备第二种格式。我试图在resultMap
上再次执行迭代。还有其他方法可以解决这个问题吗?
答案 0 :(得分:4)
实际上,你想要达到的目标非常有趣。就像你试图做某种逻辑padding
一样。我这样做的方法是使用Collectors.collectingAndThen
。一旦结果出现 - 我只需用必要的数据填充它。
请注意,我使用Sets.difference
中的guava
,但可以很容易地将其放入静态方法中。还有其他操作。
所以我认为你的MyPojo
看起来像这样:
static class MyPojo {
private final String time;
private final String name;
private final String timetaken;
public MyPojo(String time, String name, String timetaken) {
super();
this.name = name;
this.time = time;
this.timetaken = timetaken;
}
public String getName() {
return name;
}
public String getTime() {
return time;
}
public String getTimetaken() {
return timetaken;
}
public static double getTimeTakenAsDouble(MyPojo pojo) {
return Double.parseDouble(pojo.getTimetaken());
}
}
我检查过的输入数据是:
List<MyPojo> myPojos = Arrays.asList(
new MyPojo("2017", "ABC", "30"),
new MyPojo("2017", "ABC", "20"),
new MyPojo("2016", "ABC", "25"),
new MyPojo("2017", "XYZ", "40"),
new MyPojo("2018", "RDF", "80"));
以下是执行所需操作的代码:
Set<String> distinctYears = myPojos.stream().map(MyPojo::getTime).collect(Collectors.toSet());
Map<String, Map<String, Double>> resultMap = myPojos.stream()
.collect(Collectors.groupingBy(MyPojo::getName,
Collectors.collectingAndThen(
Collectors.groupingBy(MyPojo::getTime,
Collectors.averagingDouble(MyPojo::getTimeTakenAsDouble)),
map -> {
Set<String> localYears = map.keySet();
SetView<String> diff = Sets.difference(distinctYears, localYears);
Map<String, Double> toReturn = new HashMap<>(localYears.size() + diff.size());
toReturn.putAll(map);
diff.stream().forEach(e -> toReturn.put(e, 0.0));
return toReturn;
}
)));
结果是:
{ABC={2016=25.0, 2018=0.0, 2017=25.0},
RDF={2016=0.0, 2018=80.0, 2017=0.0},
XYZ={2016=0.0, 2018=0.0, 2017=40.0}}