假设我有一个每月商店销售的清单,例如:

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迅速增加,我希望有更好的解决方案...

最佳答案

您需要一个可以接受日期并返回一个budgetYearID的方法:

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())));

07-26 03:28