Stream流

Stream流式编程思想

​ --洱涷


(1)什么是Stream

Stream是一种流,是一种抽象的处理数据的思想,这种编程方式将要处理的元素集合看作一种流,流在管道中传输,然后在管道的每一个节点上对流进行操作(去重,分组,过滤…),元素流在经过管道的操作后,最后由最终操作得到新的一个元素集合。

Stream是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象所形成的一个队列,Stream并不会去储存元素,而是按照需求所进行元素计算等操作
  • 数据源流的来源可以是集合数组产生器generator
  • 聚合操作就是类似于SQL语句的操作,filter,map,reduce,find,match,sorted等。

和Collection操作不同,Stream还具有两个基础的特征:

  • Pipelining:中间的每一次操作返回的都是流对象的本身,这样多个操作就可以串联成一个管道。这样做可以对操作进行优化,比如延迟执行(laziness)和短路(short-circuiting)

    ​ 延迟执行:Stream的很多操作都是延迟执行的,例如,“查找具有三个连续元音的第一 个字符串”

    ​ 短路:传入一个谓词,返回值为Boolean,如果符合条件直接结束流,例如: findFirst(),只要找到第一个符合的,直接结束

  • 内部迭代:以前对集合遍历都是通过Iterator或for-each的方式,显式的在集合外部进行迭代,这叫外部迭代,Stream提供了内部迭代的方式,通过访问者模式实现。

(2)生成流
  • stream() − 为集合创建串行流。
  • parallelStream() − 为集合创建并行流。

串行流就是按照顺序执行一直到结束,并行流就是把内容切成多个数据块,并且利用多个线程分别处理每个数据块的内容。Stream的API中声明可以通过parallel()和sequential()方法在并行流和串行流之间切换。

注意:使用并行流并不一定能提高效率,因为jvm对数据进行切片和切换线程也是需要时间的,所以数据量越小,串行流越快,数据量越大,并行流效率越高。

JDK1.8并行流使用的是fork/join框架进行并行操作。

fork/join框架:就是在必要的情况下,将一个大任务拆分成若干个小任务(拆到不可再拆),再将一个个小任务的结果进行join汇总

这里写图片描述

(3)stream流的各种方法
1. count、anyMatch、allMatch、noneMatch

count方法和list的size()一样,返回的都是这个集合流的元素的长度,不同的一点,流是集合的一个高级工厂,中间操作是工厂里的每一道工序,我们对这个流操作完后,可以进行元素的数量和。

anyMatch表示判断的条件里,只要有一个成功,就返回true。

allMatch表示判断的条件里,所有的都要成功才会返回true。

noneMatch表示判断的条件里,所有的都不是返回true

		List<String> strs = Arrays.asList("a", "a", "a", "a", "b");
        boolean aa = strs.stream().anyMatch(str -> str.equals("a"));
        boolean bb = strs.stream().allMatch(str -> str.equals("a"));
        boolean cc = strs.stream().noneMatch(str -> str.equals("a"));
        long count = strs.stream().filter(str -> str.equals("a")).count();
        System.out.println(aa);// TRUE
        System.out.println(bb);// FALSE
        System.out.println(cc);// FALSE
        System.out.println(count);// 4
2. map、filter、flatMap

map方法:

这个方法传入了一个function函数式接口(定义了一个apply的抽象方法,接收一个泛型T对象,并且返回泛型R对象,我们在做基础数据处理的时候(eg: Integer i=0; Integer dd= i+1;),会对基础类型的包装类,进行拆箱的操作,转成基本类型,再做运算处理,拆箱和装箱,其实是非常消耗性能的,尤其是在大量数据运算的时候;这些特殊的Function函数式接口,根据不同的类型,避免了拆箱和装箱的操作,从而提高程序的运行效率)

function接口的应用例子:

 		Function<Integer, Integer> function1 = x -> x * 2;
        System.out.println(function1.apply(4));// 8
 
        Function<Integer, String> function2 = x -> x * 2 + "dd";
        System.out.println(function2.apply(4));//8dd
        
        Function<String, String> strFunction1 = (str) -> new String(str);
        System.out.println(strFunction1.apply("aa"));//aa
        
        Function<String, String> strFunction2 = String::new;
        System.out.println(strFunction2.apply("bb"));//bb
 
        Function<String, Emp> objFunction1 = (str) -> new Emp(str);
        System.out.println(objFunction1.apply("cc").getName());//cc
        
        Function<String, Emp> objFunction2 = Emp::new;
        System.out.println(objFunction2.apply("dd").getName());//dd

这个接口接收一个泛型T,返回一个泛型R,表示调用这个方法后,可以改变返回的类型,操作如下:

		Integer[] dd = {
    1, 2, 3 };
		Stream<Integer> stream = Arrays.stream(dd);
		stream.map(str -> Integer.toString(str)).forEach(str -> {
   
			System.out.println(str);// 1 ,2 ,3
			System.out.println(str.getClass());// class java.lang.String
		});
 
		List<Emp> list = Arrays.asList(new Emp("a"), new Emp("b"), new Emp("c"));
		list.stream().map(emp -> emp.getName()).for
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值