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

Java中如何对自定义Point对象列表用reduce计算Route路径总距离

错误原因

你使用的双参数reduce重载要求初始值、累加器返回值都和流元素类型保持一致。你传入的初始值是double类型的0d,流里的元素是自定义点类型T,累加器返回的distance计算结果也是double,和要求返回的T类型不匹配,因此触发类型错误。

优先用reduce的实现方案

需要用三参数的reduce重载,通过自定义累加容器同时保存上一个点和当前累计距离,实现类型转换:

兼容低版本Java的实现

public double routeDistance() {
    // 点数小于2时总距离为0
    if (points.size() < 2) {
        return 0d;
    }
    // 用Object数组作为状态容器:下标0存上一个点,下标1存累计距离
    return (double) points.stream().reduce(
        new Object[]{null, 0d},
        (acc, currentPoint) -> {
            T prevPoint = (T) acc[0];
            // 第一个点只初始化状态不计算距离
            if (prevPoint == null) {
                acc[0] = currentPoint;
                return acc;
            }
            double currentTotal = (double) acc[1] + prevPoint.distance(currentPoint);
            return new Object[]{currentPoint, currentTotal};
        },
        // 并行流的合并逻辑,串行场景也可兼容
        (acc1, acc2) -> {
            T acc1Last = (T) acc1[0];
            T acc2Last = (T) acc2[0];
            if (acc1Last == null) return acc2;
            if (acc2Last == null) return acc1;
            double mergeTotal = (double) acc1[1] + (double) acc2[1] + acc1Last.distance(acc2Last);
            return new Object[]{acc2Last, mergeTotal};
        }
    )[1];
}

Java 16+ 更优雅的record实现

// 在Route类内部定义静态累加器容器
private record DistanceAccumulator<T>(T lastPoint, double total) {}

public double routeDistance() {
    if (points.size() < 2) {
        return 0d;
    }
    return points.stream().reduce(
        new DistanceAccumulator<T>(null, 0d),
        (acc, current) -> {
            if (acc.lastPoint() == null) {
                return new DistanceAccumulator<>(current, 0d);
            }
            double newTotal = acc.total() + acc.lastPoint().distance(current);
            return new DistanceAccumulator<>(current, newTotal);
        },
        (acc1, acc2) -> {
            if (acc1.lastPoint() == null) return acc2;
            if (acc2.lastPoint() == null) return acc1;
            double mergeTotal = acc1.total() + acc2.total() + acc1.lastPoint().distance(acc2.lastPoint());
            return new DistanceAccumulator<>(acc2.lastPoint(), mergeTotal);
        }
    ).total();
}

更简洁的替代方案

如果对reduce没有强要求,用IntStream遍历索引的实现更简单易维护:

public double routeDistance() {
    return IntStream.range(0, points.size() - 1)
        .mapToDouble(i -> points.get(i).distance(points.get(i + 1)))
        .sum();
}

如果你的points是LinkedList等非随机访问列表,可以先转成数组再计算,避免多次遍历的性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:24:02