Stream 深入,并行数据

上一篇 下一篇
Stream 流 常用的设计模式

1、流合并

Stream API 中的 filter, map, sorted 这些都是聚合操作,就是对集合中的对象做整体性计算。
reduce()完整写法

.reduce((object1, object2) -> {
    
    
	··· ···
	return object;
})

简单的表达式可不用return。

小案例:

对1~10求和

import java.util.Arrays;
import java.util.List;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        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()的返回值是一个比较复杂的对象,需要调用get()返回最终值,get()返回值的类型是系统自动根据流中元素的类型推定的。

reduce()的方法参数:
第一次a是第一个元素,b是第二个元素,接下来将计算结果缓存在a中,b继续推进:
在这里插入图片描述

改进(上述的缺陷)

很明显,上面的过程将第一个元素位置当做缓存,第一个元素值已经改变。
要改进,reduce()提供了另一种参数形式,new 出一个对象充当缓冲角色,这样就不会改变流中的对象:

.reduce(new Object(), (object1, object2) -> {
    
    
	··· ···
	return object;
})

在这里插入图片描述

以上篇文章 Stream API 的 Student 类为例:

public class StudentTest {
    
    
    public static void main(String[] args) {
    
    
        List<Student> students = new ArrayList<>();
        students.add(new Student("小红", 75, 0));
        students.add(new Student("小明", 80, 0));
        students.add(new Student("小刚", 95, 1));
        students.add(new Student("小亮", 85, 0));
        students.add(new Student("小白", 83, 0));
        students.add(new Student("小强", 99, 3));
        students.add(new Student("小黑", 97, 0));
        students.add(new Student("小蓝", 86, 0));

        Student result = students.stream()
                .reduce(new Student("缓存区:", 0, 0), (a, b) -> {
    
    
                            a.setAverageScore(a.getAverageScore() + b.getAverageScore());
                            return a;
                        }
                );

        System.out.println(result.getName() + " - " + result.getAverageScore());
    }
}

输出结果:

缓存区: - 700

2、流收集

在实际运用中,整体功能比较复杂的话,使用流对集合进行计算后,可能并不像合并或输出,而是想把元素放在一个新的集合中,待进一步使用。
对于一组数字:

List<Integer> numbers = Arrays.asList(3, 2, 2, 7, 63, 2, 3, 5);

取前三个最大的放入一个新集合,并打印输出:

import java.util.List;
import java.util.stream.Collectors;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        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(number -> number + "")
                .collect(Collectors.toList());

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

输出:

字符串是: 63-7-5

collect()方法的作用是手收集元素,Collectors.toList()是一个静态方法,告诉collect()存入一个List集合,亦是collect()的返回类型。

3、并行流

在这里插入图片描述
这个管道中的每个节点依次进行,是串行,现在将它改成并行:

在这里插入图片描述
图中可以看出,每个任务虽然访问的是同一块数据区,但是它们都不改变源数据,只是各自独立计算,最终将结果合并。所以这些任务之间互不影响。
一切都已封装好,要使用,将.stream()换成parallelStream()即可。

上一篇 下一篇
Stream 流 常用的设计模式

猜你喜欢

转载自blog.csdn.net/weixin_46356818/article/details/112813077
今日推荐