流合并

对1-10的十个正整数求和:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream()
    .reduce((a, b) -> a + b)
    .get();

System.out.println("1-10求和 : " + sum);

reduce()方法的作用是合并了所有元素终止计算出一个结果,这里的终止就是流已经到达重点结束了

reduce()方法参数a在第一次执行计算语句时,指代流的第一个元素,然后充当缓存作用存放本次计算结果,此后执行计算语句时,a就是上一次的计算结果并继续充当缓存存放本次计算结果,b第一次执行是指代第二个元素,此后依次指代流的每个元素

java中求一个数的十位 java求十个数的和_java中求一个数的十位


reduce()方法还可以操作对象,但第一个对象会充当缓存角色,正确性被破坏了,所以要在添加一个参数:

Student result = students.stream()
    .reduce(new Student("", 0),
        (a, b) -> {
            a.setMidtermScore(a.getMidtermScore() + b.getMidtermScore());
            return a;
        }
    );

System.out.println(result.getName() + " - " + result.getMidtermScore());
  • 第一个参数,是作为缓存角色的对象
  • 第二个参数,是Lambda表达式完成计算

此时a变量不在是指代流中第一个元素了,专门指代缓存角色的对象

java中求一个数的十位 java求十个数的和_缓存_02


reduce()返回值变为了缓存角色的对象即第一个参数,也不再需要使用get()

流收集

对一组数字找出前三个数字放入一个新的集合中,用-组合成字符串打印

import java.util.stream.Collectors;

List<Integer> numbers = Arrays.asList(3, 2, 2, 7, 63, 2, 3, 5);
List<String> numResult = numbers.stream()
    .sorted((n1, n2) -> n2 - n1)
    .limit(3)
    .map(a -> "" + a)
    .collect(Collectors.toList());

String string = String.join("-", numResult);
System.out.println("字符串是: " + string);

collect()方法作用就是收集元素,Collectors.toList()将元素存入List集合,所以返回值就是List类型

这里map()将整数映射成字符串,所以collect()方法返回类型就是List<String>

并行流

Stream API的设计类似于管道,管道的显著特点就是每个节点依次执行,下一个节点必须等待上一个节点执行完毕,这种执行方式一般叫做串行

但串行工作模式无法发挥出多核CPU的优势,所以可以把串行计算模式改为并行计算模式

并行就是利用多线程变成同时执行,多线程可以充分发掘多核CPU的优势

java中求一个数的十位 java求十个数的和_java_03

不适合使用并行计算的场景

并行计算使用了多线程,线程输出的时机有CPU动态决定的,无法确定

流中的每个数据元素之间有逻辑依赖关系时,不适合使用并行计算

并行流的性能意外

并行计算模式的性能不是任何情况都优于串行模式

一. 硬件太差
CPU核数很低时并行计算模式不一定更好
二. 任务简单
数据量小任务简单,并行模式的多线程管理会消耗CPU内存等资源

选择

任务执行超过一小时则考虑使用并行模式优化性能,任务执行时间短有没有特别要求就使用串行模式也可以,但使用并行模式时要注意数据之间是否有逻辑关系