Java Stream流归纳

Java Stream流归纳


前言

Stream 流是什么,有什么作用,为何要引入?



💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖



一、Stream 流

第一:

  • a sequence of elements from source that supports aggregate operations
  • sequence of elements :一个流对外提供一个接口,可以访问到一串特定的数据。流不存储元素,但是可以根据需要进行计算转化
  • source:数据来源,如数据结构,数组,文件等
  • aggregate operation:聚合操作,流支持像SQL 操作或其他函数式语言的操作,如 filter/map/reduce/find/match/sorted 等

第二:

  • pipelining: 很多流操作也是返回一个流
  • Internal Iteration: 流操作进行迭代,用户感知不到循环遍历
String [] colors = {"white","black","yellow","blue","green"};
List<String> pList = Arrays.asList(colors);
//采用流方法
count = pList.stream().filter(p->p.length()>5).count();
//采用并行流方法
count = pList.parallelStream().filter(p->p.length()>5).count;

是一个链式的执行过程

流的工作流程:

  • 流的创建
  • 流的转换,将流转换为其他流的中间操作,可包括多个步骤(惰性操作)
  • 流的计算结果。这个操作会强制执行之前的惰性操作。这个步骤以后,流就再也不用了。

1、流的创建

  1. Collection 接口的 stream 方法

Stream< String > as = new ArrayList< String > ().stream();
Stream< String > hs = new HashSet< String >().stream();

还有其他的子类不在举例

  1. Arrays.stream 可以将数组转为 Stream

Stream< String > b1 = Arrays.stream(“a,b,c,d,e”.split(","),3,5);//选择第三个和第五个元素放到流里面去

  1. 利用Stream 类进行转化

    -of 方法,直接将数组转化

Stream < Integer > c1 = Stream.of(new Integer[5]);
Stream < String > c2 = Stream.of(“a,b,c”.split(","));
Stream< String > c3 = Stream.of(“a”,“b”,“c”);
-empty 方法,产生一个空流
Stream< String > d1 = Stream.empty();

generate 方法,接收一个 Lambda 表达式

Stream< String > e1 = Stream.generate(()->“hello”);
Stream< String > e2 = Stream.generate(Math::random);

iterate 方法,接收一个种子,和一个 Lambda 表达式

Stream < BigInteger > e3 = Stream.iterate(BigInteger.ZERO,n->n.add(BigInteger.ONE));

2、流的转换

Stream 转换

  • 从一种流到另外一种流(从一组数据经过计算得到另外一组数据)
  • 过滤、去重
  • 排序
  • 转化
  • 抽取、跳过、连接
  • 其他
  1. 过滤 filter
    ① filter(Predicate<? super T> predicate)
    ② 接收一个 Lambda 表达式,对每个元素进行判定,符合条件留下

    Stream<Integer> s1 = Stream.of(1,2,3,4,5);
    Stream<Integer> s2 = s1.filter(n -> n > 2);
    s2.forEach(System.out::println);
    //3,4,5
    
  2. 去重distinct
    ① distinct()
    ② 对流的元素进行过滤,去除重复,只留下不重复的元素

    Stream<Integer> s1 = Stream.of(1,1,2,2,3,3);
    Stream s2 = s1.distinct();
    s2.forEach(System.out::println);
    //1,2,3
    
    如果是复杂对象类型,则distinct方法首先根据对象的hashCode()      
     方法和equals()方法判断是否相等,来进行去重
    
  3. 排序 sorted
    ① sorted()
    ② 对流的基本类型包装类元素进行排序

     Stream<Integer> s1 = Stream.of(3,2,32,344,5);
     Stream<Integer> s2 = s1.sorted();
     s2.forEach(System.out::println);
     // 对于其他类型,我们还可以给他一个排序规则
     String [] colors = {"blue","yellow","red","green"};
     Stream< String > s3 = Stream.of(colors).sorted(Comparator.comparing(String::length));
     s3.forEach(System.out::println);  
     //或者对象已经实现了 comparable接口,实现了 compareTo ()方法
     则,默认sorted()方法会根据compareTo 的规则去比较
    
  4. 转化
    ①map
    ②利用方法引用对流每个元素进行函数计算
    ③抽取 limit
    ④跳过skip

    // map  
    Stream<Double> s1 = Stream.of(-1.5,2.5,-3.5);
    Stream<Double> s2 = s1.map(Math::abs);
    s2.forEach(System.out::println);
    
    // limit
    Stream<Double> s1 = Stream.of(1,2,3,4,5,6,7,8);
    Stream<Double> s2 = s1.limit(3);
    s2.forEach(System.out::println);
    //输出1,2,3
    
    // skip  
    Stream<Double> s1 = Stream.of(1,2,3,4,5,6,7,8,9,10);
    Stream<Double> s2 = s1.skip(8);
    s2.forEach(System.out::println);
    // 跳过8 个元素,输出9,10
     
    //还有其他方法不再展示
    

3、流的计算

首先认识一下: Optional 类型,为什么引入 Optional 类型
以前: 当我们操作一个空的对象的方法时,会报出 NullPointer Exception 的错误,而 Optional 出现就是解决这一问题,那又是怎么解决的??

  • Optional< T >:

    • 一个包装器对象
    • 要么包装了类型T 的对象,要么没有包装任何对象(还是 null)
    • 如果 T 有值,那么直接返回 T 的对象
    • 如果 T 是 null ,那么可以返回一个替代物
  • optional< T> 创建

    • of 方法

    • empty 方法

    • ofNullable 方法,对于对象有可能为空的情况下,安全创建

        Optional<String> s1 = Optional.of(new String("abc"));
        Optional<String> s2 = Optional.empty();
        String s3 = null;
        Optional<String> s4 = Optional.ofNullable(s3);
        //s3 不为空,s4 就是 s3,否则 s4 就为 Optional.empty()
        // orElse 方法:当s4 对象为空时,则返回规定的默认值,否则 返回 s4的值,这就弥补了以前对象类型的不足
        String s5 = s4.orElse("nice");
        String s6 = s1.orElse("good");
        System.out.println(s5);
        System.out.println(s6);
      
  • Optional 使用

    • get方法 ,获取值,不安全的方法
    • orElse 方法,获取值,如果为null,采用替代物的值
    • orElseGet 方法,获取值,如果为null,采用Lambda 表达式的值返回
    • orElseThrow 方法,获取值,如果为 null,抛出异常
    • ifPresent 方法,判断是否为空,不为空返回 true
    • isPresent(Consumer),判断是否为空,如果不为空,则进行后续Consumer 的操作,如果为空,则不进行任何操作
    • map(Function) ,将值传递给Function 函数进行计算。如果为空,则不进行计算

流的计算:

  • 流的计算
    - 简单约简(聚合函数): count / max / min / …
    - 自定义约简: reduce
    - 查看 / 遍历元素 : iterator / forEach
    - 存放到数据结构中

下面分别来看每一种:
流的计算:简单约简(聚合函数)

 count(), 计数
 max(Comparator) ,最大值,需要比较器
 min(Comparator),最小值,需要比较器
 findFirst(),找到第一个元素
 findAny(),找到任意一个元素(随机的返回一个元素)
 anyMatch(Predicate),如有任意一个元素满足 Predicate,返回true
 allMatch(Predicate),如果所有元素满足Predicate ,返回 true 
 noneMatch (Predicate),如果没有元素满足 Predicate ,返回true

流的计算:存放到数据结构中

toArray(),将结果转为数据
collect(Collectors.toList()),将结果转为List
collect(Collectors.toSet()),将结果转为Set
collect(Collectors.toMap()),将结果转为Map
collect(Collectors.joining()),将结果连接起来

流的高阶计算:

分组groupingBy 和 分区 partitionBy
分组后的简约
counting
summing
maxBy
minBy
以上方法均在 java.util.stream.Collectors 中

二、总结

JavaStream 的优点:

  • 统一转换元素
  • 过滤元素
  • 利用单个操作合并元素
  • 将元素序列存放到某一个集合中
  • 搜索满足某些条件的序列
  • 类似SQL操作,遵循 “做什么而非做什么” 原则
  • 简化了串行/ 并行的大批量操作
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值