假设我有一份月度商店销售清单,以便:
ID, date, amount
1, Jan 2016, $500
2, Feb 2017, $200
3, October 2017, $300
我的财政年度是2016年9月1日到2017年8月31日。换句话说,前两个项目在一个会计年度,另一个在第二个会计年度。实际会计年度是特定于用户的。
我想为每个会计年度创建一个storeSales
列表。
到目前为止,我有:
Map<fiscalYearID, List<StoreSale> = storeSales.stream()
.collect(
Collectors.groupingBy(
storeSale -> storeSale.getSaleLocalDate()));
问题是上面的代码只会按确切日期分组。我可以添加.getYear()
但that would only group by year and NOT fiscal year。我还想过为每个会计年度日期范围使用Stream.iterate()
,然后将该日期范围内所有商店的商店销售列表列入一个列表,但这样做非常难看,大O值开始很快爬。那将是这样的:
Stream.iterate(startDate, date -> date.plusMonths(1))
.limit(ChronoUnit.MONTHS.between(startDate, endDate.plusMonths(1)))
.forEach(
{
addToFiscalYear(fiscalYearID,
storeSales.stream().
.filter(storeSale -> storeSale.getSaleLocalDate().equals(date))
.collect(Collectors.toList());
});
或类似的东西。我没有太多探索,因为它的大O快速增加,我希望有更好的解决方案......
答案 0 :(得分:6)
您需要一个接受日期并返回fiscalYearID的方法:
public static fiscalYearID getFiscalYearID (Date date)
{
// return fiscal year ID matching passed date
}
现在您可以按fiscalYearID
进行分组(假设fiscalYearID
是一个覆盖equals
的类):
Map<fiscalYearID, List<StoreSale>> =
storeSales.stream()
.collect(Collectors.groupingBy(s -> getFiscalYearID (s.getSaleLocalDate())));
答案 1 :(得分:3)
您可以做以下事情:
由于会计年度由用户确定,因此您可以计算会计年度的抵消额。例如,如果会计年度从9月开始,则抵消将为9个月。通过减去9个月,您可以map
财政年度到正常年份。使用Java 8 date API应该很容易。然后,您可以使用通常的groupingBy(storeSale -> storeSale.getSaleLocalDate().getYear())
对日期进行分组。