流合并
对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第一次执行是指代第二个元素,此后依次指代流的每个元素
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变量不在是指代流中第一个元素了,专门指代缓存角色的对象
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的优势
不适合使用并行计算的场景
并行计算使用了多线程,线程输出的时机有CPU动态决定的,无法确定
流中的每个数据元素之间有逻辑依赖关系时,不适合使用并行计算
并行流的性能意外
并行计算模式的性能不是任何情况都优于串行模式
一. 硬件太差
CPU核数很低时并行计算模式不一定更好
二. 任务简单
数据量小任务简单,并行模式的多线程管理会消耗CPU内存等资源
选择
任务执行超过一小时则考虑使用并行模式优化性能,任务执行时间短有没有特别要求就使用串行模式也可以,但使用并行模式时要注意数据之间是否有逻辑关系