reduce()简介

  • Reduce 原意:减少,缩小

  • 根据指定的计算模型将Stream中的值计算得到一个最终结果
    解释:reduce 操作可以实现从Stream中生成一个值,其生成的值不是随意的,而是根据指定的计算模型。比如,之前提到count、min和max方法,因为常用而被纳入标准库中。事实上,这些方法都是reduce操作。

reduce三个override的方法

reduce方法有三个override的方法:

Optional<T> reduce(BinaryOperator<T> accumulator);
T reduce(T identity, BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)

事例集合

测试代码中的所有集合,都是该集合。

List<Person> javaProgrammers = new ArrayList<Person>() {{add(new Person("Elsdon", "Jaycob", "Java programmer", "male", 2000, 18));add(new Person("Tamsen", "Brittany", "Java programmer", "female", 2371, 55));add(new Person("Floyd", "Donny", "Java programmer", "male", 3322, 25));add(new Person("Sindy", "Jonie", "Java programmer", "female", 35020, 15));add(new Person("Vere", "Hervey", "Java programmer", "male", 2272, 25));add(new Person("Maude", "Jaimie", "Java programmer", "female", 2057, 87));add(new Person("Shawn", "Randall", "Java programmer", "male", 3120, 99));add(new Person("Jayden", "Corrina", "Java programmer", "female", 345, 25));add(new Person("Palmer", "Dene", "Java programmer", "male", 3375, 14));add(new Person("Addison", "Pam", "Java programmer", "female", 3426, 20));}
}

方式一reduce(BinaryOperator accumulator)

  • Optional<T> reduce(BinaryOperator<T> accumulator);
    我们先看第一个变形,参数列表为一个函数接口BinaryOperator<T>,
    BinaryOperator源码:


public interface BinaryOperator<T> extends BiFunction<T,T,T> {public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;}public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {Objects.requireNonNull(comparator);return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;}
}

看BinaryOperator接口源码,我们可以看到,它又继承了BiFunction<T,T,T>.

另外,在BinaryOperator接口中又定义了另个静态方法为minBy和maxBy,

上面我们提到BinaryOperator接口继承了BiFunction<T,T,T>,我们看一下BiFunction<T,T,T>源码:

@FunctionalInterface
public interface BiFunction<T, U, R> {R apply(T t, U u);//接收两个参数 t 和 u, 返回 R
}

Bifunction中有一个apply方法,接收两个参数,返回一个结果

小结: 不管是BinaryOperator类还是最终继承的BiFunction类,在类上都有@FunctionalInterface注解,因此reduce(BinaryOperator<T> accumulator)方法需要一个函数式接口参数,该函数式接口需要两个参数,返回一个结果(reduce中返回的结果会作为下次累加器计算的第一个参数),也就是累加器,最终得到一个Optional对象

测试示例代码:

    @Testpublic void Test() {int asInt = javaProgrammers.stream().mapToInt(Person::getSalary)//返回数值流,减少拆箱封箱操作,避免占用内存  IntStream.reduce((x, y) -> x += y)// int.getAsInt(); //return intSystem.out.printf("方式一   reduce(BinaryOperator<T> accumulator)   求薪资测试结果:"+asInt);/*解析:1. reduce(BinaryOperator<T> accumulator)    reduce方法接受一个函数,这个函数有两个参数2. 第一个参数是上次函数执行的返回值(也称为中间结果),第二个参数是stream中的元素,这个函数把这两个值相加,得到的和会被赋值给下次执行这个函数的第一个参数*注意:1.第一次执行的时候第一个参数的值是Stream的第一个元素,第二个参数是Stream的第二个元素2.方法返回值类型是Optional*/}

方式二reduce(T identity, BinaryOperator accumulator)

  • T reduce(T identity, BinaryOperator<T> accumulator);
    与第一种变形相同的是都会接受一个BinaryOperator函数接口,不同的是其会接受一个identity参数,identity参数与Stream中数据同类型,相当于一个的初始值,通过累加器accumulator迭代计算Stream中的数据,得到一个跟Stream中数据相同类型的最终结果。
    测试示例代码:

    @Testpublic void test1(){int reduce = javaProgrammers.stream().mapToInt(Person::getSalary).reduce(10000, (x, y) -> x += y);System.out.printf("方式二  reduce(T identity, BinaryOperator<T> accumulator)   求薪资测试结果:"+reduce);/*注意:*      1.与方式一相比设置了累加器的初始值,参数一(x)则不再是Stream中的第一个数据而是设置的初始值(10000)其他相同*/}

打印结果:

方式一   reduce(BinaryOperator<T> accumulator)   求薪资测试结果:57308
方式二  reduce(T identity, BinaryOperator<T> accumulator) 求薪资测试结果:67308 //初始值10000

方式三 reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)

  • \<U\> U reduce(U identity,BiFunction\<U, ? super T, U\> accumulator,BinaryOperator\<U\> combiner);
    我们先观察分析再次被改变的参数列表:

1. 第一个参数:返回实例u,传递你要返回的U类型对象的初始化实例u

2. 第二个参数:累加器accumulator,可以使用lambda表达式,声明你在u上累加你的数据来源t的逻辑,例如(u,t)->u.sum(t),此时lambda表达式的行参列表是返回实例u和遍历的集合元素t,函数体是在u上累加t

3. 第三个参数:参数组合器combiner,接受lambda表达式。

根据参数我们一步一步分析代码示例:

    @Testpublic void test2() {ArrayList<Integer> accResult_ = Stream.of(1, 2, 3, 4)//第一个参数,初始值为ArrayList.reduce(new ArrayList<Integer>(),//第二个参数,实现了BiFunction函数式接口中apply方法,并且打印BiFunctionnew BiFunction<ArrayList<Integer>, Integer, ArrayList<Integer>>() {@Overridepublic ArrayList<Integer> apply(ArrayList<Integer> acc, Integer item) {acc.add(item);System.out.println("item: " + item);System.out.println("acc+ : " + acc);System.out.println("BiFunction");return acc;}//第三个参数---参数的数据类型必须为返回数据类型,改参数主要用于合并多个线程的result值// (Stream是支持并发操作的,为了避免竞争,对于reduce线程都会有独立的result)}, new BinaryOperator<ArrayList<Integer>>() {@Overridepublic ArrayList<Integer> apply(ArrayList<Integer> acc, ArrayList<Integer> item) {System.out.println("BinaryOperator");acc.addAll(item);System.out.println("item: " + item);System.out.println("acc+ : " + acc);System.out.println("--------");return acc;}});System.out.println("accResult_: " + accResult_);System.out.println("------------------lambda优化代码-----------------");ArrayList<Integer> newList = new ArrayList<>();ArrayList<Integer> accResult_s = Stream.of(1,2,3,4).reduce(newList,(acc, item) -> {acc.add(item);System.out.println("item: " + item);System.out.println("acc+ : " + acc);System.out.println("BiFunction");return acc;}, (acc, item) -> null);System.out.println("accResult_s: " + accResult_s);}

示例代码中,第一个参数是ArrayList,在第二个函数参数中打印了“BiFunction”,而在第三个参数接口中打印了函数接口中打印了”BinaryOperator“.看下面的打印结果,只打印了“BiFunction”,而没有打印”BinaryOperator“,也就是说第三个函数参数并没有执行。分析参数时我们知道了该变形可以返回任意类型的数据。

对于第三个函数参数,为什么没有执行,而且其参数必须为返回的数据类型?这是因为Stream是支持并发操作的,为了避免竞争,对于reduce线程都会有独立的result,combiner的作用在于合并每个线程的result得到最终结果。这也说明了了第三个函数参数的数据类型必须为返回数据类型了。 java8 reduce方法中的第三个参数combiner有什么作用?

打印结果:

item: 1
acc+ : [1]
BiFunction
item: 2
acc+ : [1, 2]
BiFunction
item: 3
acc+ : [1, 2, 3]
BiFunction
item: 4
acc+ : [1, 2, 3, 4]
BiFunction

另外需要注意:因为第三个参数用来处理并发操作,如何处理数据的重复性,应多做考虑,否则会出现重复数据!

JAVA8 Stream流之reduce()方法详解相关推荐

  1. Java8 Stream流式操作接口详解

    stream是用于集合使用的流式操作,可使用collection.stream获取流 default Stream<E> stream() {return StreamSupport.st ...

  2. java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

    java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用

  3. Java8 Stream 中的 reduce() 方法,执行聚合操作

    初识 Stream 中的 reduce() 方法,是在最近一次刷算法题的过程中(下面会讲到),简洁干练的写法,让我眼前一亮. 所以,我简单学习了,总结了一下写法: 正文 Java 8 API添加了一个 ...

  4. [五]java函数式编程归约reduce概念原理 stream reduce方法详解 reduce三个参数的reduce方法如何使用...

    reduce-归约 看下词典翻译: 好的命名是自解释的 reduce的方法取得就是其中归纳的含义 java8 流相关的操作中,我们把它理解 "累加器",之所以加引号是因为他并不仅仅 ...

  5. java8 reduce的用法_Java8中聚合操作collect、reduce方法详解

    下面我们一起来了解一下关于Java8中聚合操作collect.reduce方法,希望这篇文章能够帮助到各位java初学者. Stream的基本概念 Stream和集合的区别: Stream不会自己存储 ...

  6. JS进阶篇--JS数组reduce()方法详解及高级技巧

    基本概念 reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值. reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被 ...

  7. js的parseInt() map(),reduce()方法详解

    parseInt(string,radius)接收两个参数, string(必选)如果接受的是'abc',纯字符串,返回NaN,要是'123'会转化为123,要是'abc123'会转化为123,rad ...

  8. 二维数组各行求和_JS数组reduce()方法详解及高级技巧

    reduce()方法可以搞定的东西,for循环,或者forEach方法有时候也可以搞定,那为啥要用reduce()?这个问题,之前我也想过,要说原因还真找不到,唯一能找到的是:通往成功的道路有很多,但 ...

  9. JS进阶篇--JS数组reduce()方法详解及高级技巧 1

    基本概念 reduce() 方法接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始缩减,最终为一个值. reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被 ...

最新文章

  1. 转 让开发自动化: 使用自动化加速部署
  2. (转)android WebView loadData不能解析(找不到网页)
  3. React ref的转发
  4. win10一直卡在自动修复_分享:win10自动修复过程中无法正确启动怎么办?
  5. 车牌号专用键盘设计和正则验证
  6. Spring5.0(2)--- Framework 5 FAQ
  7. 外星人17r4原版系统_外星人Alienware 17R4 测评/升级
  8. android 监听短信并发送到服务器
  9. “驱动人生”升级通道传木马,技术分析报告来了
  10. 【实战技能】软件工程师与AI工程师的区别是什么?
  11. firefly-rk3288开发板Linux驱动——AT24C02 E2PROM驱动
  12. omap3isp上层应用解析
  13. Qt保存QTextEdit内存至.txt文件中
  14. 哪家的云服务器便宜?
  15. Ubuntu虚拟机中网络中没有网卡
  16. C语言中fscanf()函数的用法介绍
  17. windows10系统解除微软账户和本地账户绑定
  18. Unity之手机键盘自定义输入栏位置适配不同手机分辨率适配
  19. Python函数之生成器
  20. ​给各位股东汇报一下我的 2021 年计划

热门文章

  1. SPOJ MARBLES
  2. python多线程爬取淘宝商家图片
  3. 抖音矩阵号运营工具应该注意的关键事项丨抖音账号矩阵系统源码开发
  4. powerdesigner 怎么关联两张表_【PL/SQL数据库】 三种关联机制 - 执行计划
  5. SpringBoot 使用MultipartFile上传组件实现本地上传用户头像
  6. Grunt插件之uglify--js代码压缩与合并
  7. swagger学习日记1 swagger测试接口时传入参数的类型问题
  8. npm常用命令学习(npm install -D,semver版本规范, npm进行版本管理的最佳实践用法)...
  9. 使用AI写作工具,进阶文案写手:WordHero AI
  10. [论文笔记] Methodologies for Data Quality Assessment and Improvement (ACM Comput.Surv, 2009) (1)