阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用reduce

30次阅读
没有评论

共计 1902 个字符,预计需要花费 5 分钟才能阅读完成。

map()filter() 都是 Stream 的转换方法,而 Stream.reduce() 则是 Stream 的一个聚合方法,它可以把一个 Stream 的所有元素按照聚合函数聚合成一个结果。

我们来看一个简单的聚合方法:

import java.util.stream.*;

public class Main {public static void main(String[] args) {int sum = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(0, (acc, n) -> acc + n);
        System.out.println(sum); // 45
    }
}

reduce()方法传入的对象是 BinaryOperator 接口,它定义了一个 apply() 方法,负责把上次累加的结果和本次的元素
进行运算,并返回累加的结果:

@FunctionalInterface
public interface BinaryOperator<T> {// Bi 操作:两个输入,一个输出
    T apply(T t, T u);
}

上述代码看上去不好理解,但我们用 for 循环改写一下,就容易理解了:

Stream<Integer> stream = ...
int sum = 0;
for (n : stream) {sum = (sum, n) -> sum + n;
}

可见,reduce()操作首先初始化结果为指定值(这里是 0),紧接着,reduce()对每个元素依次调用 (acc, n) -> acc + n,其中,acc 是上次计算的结果:

// 计算过程:
acc = 0 // 初始化为指定值
acc = acc + n = 0 + 1 = 1 // n = 1
acc = acc + n = 1 + 2 = 3 // n = 2
acc = acc + n = 3 + 3 = 6 // n = 3
acc = acc + n = 6 + 4 = 10 // n = 4
acc = acc + n = 10 + 5 = 15 // n = 5
acc = acc + n = 15 + 6 = 21 // n = 6
acc = acc + n = 21 + 7 = 28 // n = 7
acc = acc + n = 28 + 8 = 36 // n = 8
acc = acc + n = 36 + 9 = 45 // n = 9

因此,实际上这个 reduce() 操作是一个求和。

如果去掉初始值,我们会得到一个Optional<Integer>

Optional<Integer> opt = stream.reduce((acc, n) -> acc + n);
if (opt.isPresent()) {System.out.println(opt.get());
}

这是因为 Stream 的元素有可能是 0 个,这样就没法调用 reduce() 的聚合函数了,因此返回 Optional 对象,需要进一步判断结果是否存在。

利用 reduce(),我们可以把求和改成求积,代码也十分简单:

import java.util.stream.*;

public class Main {public static void main(String[] args) {int s = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9).reduce(1, (acc, n) -> acc * n);
        System.out.println(s); // 362880
    }
}

注意:计算求积时,初始值必须设置为1

除了可以对数值进行累积计算外,灵活运用 reduce() 也可以对 Java 对象进行操作。下面的代码演示了如何将配置文件的每一行配置通过 map()reduce()操作聚合成一个Map<String, String>

import java.util.*;

public class Main {public static void main(String[] args) {// 按行读取配置文件:
        List<String> props = List.of("profile=native", "debug=true", "logging=warn", "interval=500");
        Map<String, String> map = props.stream()
                // 把 k = v 转换为 Map[k]=v:
                .map(kv -> {String[] ss = kv.split("\\=", 2);
                    return Map.of(ss[0], ss[1]);
                })
                // 把所有 Map 聚合到一个 Map:
                .reduce(new HashMap<String, String>(), (m, kv) -> {m.putAll(kv);
                    return m;
                });
        // 打印结果:
        map.forEach((k, v) -> {System.out.println(k + "=" + v);
        });
    }
}

小结

reduce()方法将一个 Stream 的每个元素依次作用于BinaryOperator,并将结果合并。

reduce()是聚合方法,聚合方法会立刻对 Stream 进行计算。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计1902字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中