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

如何用Java 8 Stream按元素比较两个列表并优化代码?

更优雅的Java 8 Stream实现compareTriplets方法

这是一道算法任务:遍历两个列表a和b的对应元素,若a[i] > b[i]则Alice得1分;若a[i] < b[i]则Bob得1分;相等则双方不得分,最终返回包含Alice得分和Bob得分的列表[Alice得分, Bob得分]。

原始循环实现

public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
    int alice = 0;
    int bob = 0;
    for (int i = 0; i < a.size(); i++) {
        if (a.get(i) > b.get(i)) 
            alice++;
        else if (a.get(i) < b.get(i)) 
            bob++;
    }
    return Arrays.asList(alice, bob);
}

你尝试的Stream实现

public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
    Integer[] result = {0, 0};
    IntStream.range(0, Math.min(a.size(), b.size()))
            .map(i -> a.get(i).compareTo(b.get(i)))
            .forEach(i -> {
                if (i > 0) result[0]++;
                else if (i < 0) result[1]++;
            });
    return Arrays.asList(result);
}

更简洁优雅的Stream写法

写法一:分两次统计(高可读性)

这种写法逻辑直观、代码简洁,适合列表规模不大的场景:

public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
    int size = Math.min(a.size(), b.size());
    int alice = (int) IntStream.range(0, size)
            .filter(i -> a.get(i) > b.get(i))
            .count();
    int bob = (int) IntStream.range(0, size)
            .filter(i -> a.get(i) < b.get(i))
            .count();
    return Arrays.asList(alice, bob);
}

写法二:单次遍历归约(函数式风格)

通过reduce操作在单次遍历中完成得分统计,避免外部可变容器:

public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
    int[] scores = IntStream.range(0, Math.min(a.size(), b.size()))
            .map(i -> a.get(i).compareTo(b.get(i)))
            .reduce(new int[]{0, 0}, (acc, cmp) -> {
                if (cmp > 0) acc[0]++;
                else if (cmp < 0) acc[1]++;
                return acc;
            }, (acc1, acc2) -> {
                acc1[0] += acc2[0];
                acc1[1] += acc2[1];
                return acc1;
            });
    return Arrays.asList(scores[0], scores[1]);
}

写法三:自定义收集器(复用性更强)

用自定义收集器封装得分统计逻辑,后续如需调整规则可直接修改收集器:

public static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
    return IntStream.range(0, Math.min(a.size(), b.size()))
            .map(i -> a.get(i).compareTo(b.get(i)))
            .collect(Collector.of(
                    () -> new int[]{0, 0},
                    (acc, cmp) -> {
                        if (cmp > 0) acc[0]++;
                        else if (cmp < 0) acc[1]++;
                    },
                    (acc1, acc2) -> {
                        acc1[0] += acc2[0];
                        acc1[1] += acc2[1];
                        return acc1;
                    },
                    acc -> Arrays.asList(acc[0], acc[1])
            ));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:25:41