如何使用Java Stream API统计小吃店每日客流总量
实现方案
完全可以通过Stream API简化实现,核心思路是把每条预订记录扁平映射为「日期-对应客流」的条目,再直接分组累加即可,无需手动判断哈希表是否存在对应键,简化后代码如下:
import java.time.LocalDate; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.IntStream; public class SnackBarOccupanceTest { public static void main(String args[]){ SnackBarStat snackBarStat1 = new SnackBarStat(); snackBarStat1.setStartDate(LocalDate.of(2021, 9, 13)); snackBarStat1.setCustomers(2); snackBarStat1.setNumberOfDays(3); SnackBarStat snackBarStat2 = new SnackBarStat(); snackBarStat2.setStartDate(LocalDate.of(2021, 9, 12)); snackBarStat2.setCustomers(3); snackBarStat2.setNumberOfDays(2); SnackBarStat snackBarStat3 = new SnackBarStat(); snackBarStat3.setStartDate(LocalDate.of(2021, 9, 13)); snackBarStat3.setCustomers(1); snackBarStat3.setNumberOfDays(1); List<SnackBarStat> snackBarStats = List.of(snackBarStat1, snackBarStat2, snackBarStat3); // Stream API实现核心逻辑 Map<LocalDate, Integer> occupancePerDate = snackBarStats.stream() .flatMap(stat -> IntStream.range(0, stat.getNumberOfDays()) .mapToObj(i -> Map.entry(stat.getStartDate().plusDays(i), stat.getCustomers())) ) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.summingInt(Map.Entry::getValue) )); System.out.println(occupancePerDate); } }
代码说明
- 用
IntStream.range替代了单独的expandDates展开日期方法,直接在流内完成日期展开,省略了额外的工具方法 - 用
flatMap把每条预订记录转换为它覆盖的所有日期的客流条目 - 用
Collectors.groupingBy+Collectors.summingInt直接完成分组求和,无需手动处理空值判断 - 运行输出和原有实现完全一致:
{2021-09-12=3, 2021-09-13=6, 2021-09-14=2, 2021-09-15=2}
内容的提问来源于stack exchange,提问作者Sandeep Nair
相关产品推荐
相关产品推荐

