我有一个Map
个对象列表,如下所示:
year => 2016,
month => 10,
day => 11,
count => 123
我在startDate
<范围内每天都有一个元素。 endDate
。
我希望能够根据startDate
和endDate
之间的时间间隔将这些元素缩减为不同的时间分组。如果startDate
和endDate
之间的差异大于4年,我想将它们分组为数年。如果差异小于四年,但大于一年,我想将它们分成几个月。如果它不到一年,但超过一个月,我想分成几周。不到一个月的任何事情,没有必要的分组。
当我说“群组”时,我的意思是我想总结属于特定年份的所有内容的count
元素(使用上面的第一个示例),并返回单个每年的地图如下所示:
year => 2016,
month => 1
day => 1
count => 9897
我知道必须有一种优雅的方法来实现这一目标,但我很难将我的大脑包裹在逻辑之中。
答案 0 :(得分:2)
我不明白,你可以这样做:
if(starDate is smaller then endDate by 4 year) {
resultMap = yourList.stream()
.collect(Collectors.groupingBy(map.get("year"),
Collectors.summingInt(map.get("count")));
}
else if(starDate is... another condition) {
resultMap = yourList.stream()
.collect(Collectors.groupingBy(map.get("month"),
Collectors.summingInt(map.get("count")));
}
// all the there cases...
稍后将此结果映射到您想要的任何内容。
答案 1 :(得分:2)
像往常一样使用Collectors.groupingBy
并提供您想要的分类器。
final LocalDate endDate = dateCounts.last().getDate();
Function<DateCount, LocalDate> mapLocalDate = dc-> {
LocalDate ld = dc.getDate();
long m = Period.between(ld, endDate ).toTotalMonths();
if ( m > 4*12 ) {
return ld.withMonth(1).withDayOfMonth(1);
} else if ( m >= 1 ) {
return ld.withDayOfMonth(1);
} else {
return ld;
}
};
Map<LocalDate, Long> r = dateCounts.stream()
.collect(Collectors.groupingBy(
mapLocalDate,
TreeMap::new,
Collectors.summingLong(DateCount::getCount)
)
);
System.out.println( "EndDate = " + endDate );
System.out.println( r );