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

仅使用reduce函数能否将Java Stream<T>归约为同类型的新Stream<T>

实现方案

完全可以用单个reduce运算符实现,不需要嵌套多层groupingBy,特别适合匹配层级多的场景,代码结构不会随匹配字段增加变复杂。

核心思路

用Map作为reduce的中间容器,key是你需要匹配的所有属性的组合,value是累加后的Animal对象,每次处理元素时直接合并对应key的age值,最后提取Map的values即可。

代码示例

Java 16+ 版本(推荐,用Record做组合键,避免哈希冲突)

先定义组合键,把所有需要匹配的字段都放进去,后续新增匹配字段只需要修改这个Record即可:

// 组合键:所有需要匹配去重的字段
record AnimalKey(String typeOfAnimal, String breed) {}

Stream<Animal> results = animals.stream()
    .reduce(
        // 初始容器:空HashMap
        new HashMap<AnimalKey, Animal>(),
        // 单元素累加逻辑
        (accMap, currentAnimal) -> {
            AnimalKey key = new AnimalKey(currentAnimal.getTypeOfAnimal(), currentAnimal.getBreed());
            accMap.merge(
                key,
                currentAnimal,
                (existed, newVal) -> new Animal()
                    .withTypeOfAnimal(existed.getTypeOfAnimal())
                    .withBreed(existed.getBreed())
                    .withAge(existed.getAge() + newVal.getAge())
            );
            return accMap;
        },
        // 并行流场景下的容器合并逻辑
        (leftMap, rightMap) -> {
            rightMap.forEach((key, val) -> 
                leftMap.merge(
                    key,
                    val,
                    (existed, newVal) -> new Animal()
                        .withTypeOfAnimal(existed.getTypeOfAnimal())
                        .withBreed(existed.getBreed())
                        .withAge(existed.getAge() + newVal.getAge())
                )
            );
            return leftMap;
        }
    )
    .values()
    .stream();

低版本Java兼容方案

没有Record的情况下可以用List.of()当组合键,List的equals和hashCode默认按元素匹配,也能实现效果:

Stream<Animal> results = animals.stream()
    .reduce(
        new HashMap<List<String>, Animal>(),
        (accMap, currentAnimal) -> {
            List<String> key = List.of(currentAnimal.getTypeOfAnimal(), currentAnimal.getBreed());
            accMap.merge(
                key,
                currentAnimal,
                (existed, newVal) -> new Animal()
                    .withTypeOfAnimal(existed.getTypeOfAnimal())
                    .withBreed(existed.getBreed())
                    .withAge(existed.getAge() + newVal.getAge())
            );
            return accMap;
        },
        (leftMap, rightMap) -> {
            rightMap.forEach((key, val) -> 
                leftMap.merge(
                    key,
                    val,
                    (existed, newVal) -> new Animal()
                        .withTypeOfAnimal(existed.getTypeOfAnimal())
                        .withBreed(existed.getBreed())
                        .withAge(existed.getAge() + newVal.getAge())
                )
            );
            return leftMap;
        }
    )
    .values()
    .stream();

优势说明

  • 不需要嵌套多层groupingBy,后续新增匹配维度只需要给组合键加字段即可,代码结构完全不变
  • 逻辑更内聚,所有累加规则都在merge函数里,修改更方便
  • 同时兼容串行和并行流场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 07:06:04