You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17 Stream API实现查找最接近今日日期的预测值

Java 17 无状态Stream实现近期预测值提取

需求说明

需要实现的业务逻辑规则如下:

  • 方法入参接收Collection<ForecastPerDate>类型集合,该数据结构为Java 17 record类型,定义为:
    public record ForecastPerDate(String date, Double value) {}
    
  • 过滤集合中日期大于等于当日的当日/未来条目
  • 筛选出日期与当日差值最小(最接近今日)的条目,提取其value字段
  • 对提取到的数值先执行floor向下取整,再执行round四舍五入,最终转换为Long类型返回
  • 若集合为空、无符合过滤条件的条目或数值为空,打印对应业务日志后兜底返回0

原有命令式实现

最初采用传统循环+可变变量的命令式范式实现,存在临时可变状态、额外Map存储的开销,代码如下:

@Override
    public Long getAvailabilityFromForecastData(final String fuCode,
                                                final String articleCode,
                                                final Collection<ForecastPerDate> forecasts) {
        if (forecasts == null || forecasts.isEmpty()) {
            log.info(
                    "No forecasts received for FU {} articleCode {}, assuming 0!",
                    fuCode,
                    articleCode
            );
            return 0L;
        }

        final long todayEpochDay = LocalDate.now().toEpochDay();
        final Map<String, Double> forecastMap = new HashMap<>();
        long smallestDiff = Integer.MAX_VALUE;
        String smallestDiffDate = null;

        for (final ForecastPerDate forecast : forecasts) {
            final long forecastEpochDay = LocalDate.parse(forecast.date()).toEpochDay();
            final long diff = forecastEpochDay - todayEpochDay;

            if (diff >= 0 && diff < smallestDiff) {
                // 仅匹配当日及未来数据
                smallestDiff = diff;
                smallestDiffDate = forecast.date();
                forecastMap.put(forecast.date(), forecast.value());
            }
        }

        if (smallestDiffDate != null) {
            final Double wantedForecastValue = forecastMap.get(smallestDiffDate);
            if (wantedForecastValue != null) {
                return availabilityAmountFormatter(wantedForecastValue);
            }
        }

        log.info(
                "Resorting to fallback for FU {} articleCode {}, 0 availability for article!  Forecasts: {}",
                fuCode,
                articleCode,
                forecasts
        );
        return 0L;
    }

    private Long availabilityAmountFormatter(final Double raw) {
        return Math.round(Math.floor(raw));
    }

函数式无状态Stream实现

基于Java 17 Stream API完成优化,全程仅单次遍历流,无额外中间集合存储开销,无临时可变变量,完全符合函数式无状态的编码要求,代码如下:

private static long toEpochDay(final String date) {
        return LocalDate.parse(date).toEpochDay();
    }

    @Override
    public Long getAvailabilityFromForecastData(final String fuCode,
                                                final String articleCode,
                                                final Collection<ForecastPerDate> forecasts) {
        final long today = LocalDate.now().toEpochDay();
        final String fallbackMessage = "Resorting to fallback for FU {} articleCode {},"
                + " 0 availability for article! Forecasts: {}";

        if (forecasts == null) {
            log.info(fallbackMessage, fuCode, articleCode, null);
            return 0L;
        }

        final Optional<ForecastPerDate> nearestValidForecast = forecasts.stream()
                // 若需包含当日数据,此处条件调整为 toEpochDay(fpd.date()) >= today
                .filter(fpd -> toEpochDay(fpd.date()) > today)
                .min(Comparator.comparingLong(fpd -> toEpochDay(fpd.date()) - today));

        return nearestValidForecast
                .map(ForecastPerDate::value)
                .map(this::availabilityAmountFormatter)
                .orElseGet(() -> {
                    log.info(fallbackMessage, fuCode, articleCode, forecasts);
                    return 0L;
                });
    }

    private Long availabilityAmountFormatter(final Double raw) {
        return Math.round(Math.floor(raw));
    }

实现说明:直接使用Stream的min终端操作,按日期与今日的差值做比较,天然适配「找最小差值元素」的需求,不需要手动实现reduce累加器逻辑,流框架本身已经做了单次遍历优化,不会产生额外迭代开销;同时用Optional的链式分支方法替代手动if判断,逻辑更紧凑,完全规避可变临时变量,也避免了手动调用Optional.get()可能产生的异常风险。


内容的提问来源于stack exchange,提问作者Josep Bigorra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 00:48:20