zoukankan      html  css  js  c++  java
  • java-stream

    java8-Stream

    什么是 Stream?

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

    • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
    • 数据源* 流的来源。 可以是集合数组I/O channel产生器generator 等。
    • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

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

    • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
    • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现

    ​ ————————以上是菜鸟教程的说明

    接下来还是菜鸟教程的内容

    首先是生成流的类别

    • 串行流 stream()
    • 并行流 parallelStream()

    串行流

    首先来看一下一个小的demo

    List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
    List<String> filtered = strings.stream()
                            .filter(string -> !string.isEmpty())
                            .collect(Collectors.toList());
    filtered.forEach(System.out::println);
    
    输出结果:
    abc
    bc
    efg
    abcd
    jkl
    
    

    forEach

    Random random = new Random();
    random.ints().limit(10).forEach(System.out::println);
    
    用ints()生成的对象是 IntStream 类型的对象,是int值流
    
    • random.ints()
      • 用于得到一个有效无限的伪随机 int 值流
        • 带有一个参数的时候,得到传入参数个的有效无限的伪随机int值流
        • 带有两个参数的时候,得到在这个范围内的int流值,如果不设置limit(个数)的话,会无限生成
    • limit()
      • 用来限制生成多少个值(在此处的理解)

    map

    map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

    List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    // 获取对应的平方数
    List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
    squaresList.forEach(System.out::println);
    结果:
    9
    4
    49
    25
    
    • distinct() 此函数是用来去重的函数

    filter

    filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:

    List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    // 获取空字符串的数量
    long count = strings.stream().filter(string -> string.isEmpty()).count();
    
     List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
    List<String> list = strings.stream().filter(string->!string.isEmpty()).map(string->
    " "+string+" ").collect(Collectors.toList());
    list.forEach(System.out::println);
    输出结果:
     abc 
     bc 
     efg 
     abcd 
     jkl 
    

    可以多个方法链式使用,以达到自己的目的

    collect(Collectors.toList())将自己的流数据冲到list集合里面去

    limit

    limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:

    Random random = new Random();
    random.ints().limit(10).forEach(System.out::println);
    

    sorted

    sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:

    Random random = new Random();
    random.ints().limit(10).sorted().forEach(System.out::println);
    输出结果:
    -1560117986
    -1364889229
    -1336273802
    -1272156577
    -1143677960
    -659024975
    -520656633
    1433415374
    1633707646
    1972427861
    
    
    • 显然使用sorted()方法对结果集默认使用的是从小到大进行排序
    /**
    * Returns a stream consisting of the elements of this stream in sorted
    * order.
    *
    * <p>This is a <a href="package-summary.html#StreamOps">stateful
    * intermediate operation</a>.
    *
    * @return the new stream
    */
    IntStream sorted();
    官方给的说明
    

    如果想使用逆序排序的话

    此博客上找出了可以实现的方法

    由此展开说明

    • 首先是如果元素类想使用sorted进行排序,则元素类必须实现Comparable接口

    • 自然降序则需要使用Comparator.reverseOrder()作为sorted的参数

    • List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
      list.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println);
      输出结果:
      7
      6
      5
      4
      3
      2
      1
      
    • 如果想对自己定义的类进行排序,可以参照上方的博客进行细读和研讨

    统计

    另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。

    List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    
    IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
    
    System.out.println("列表中最大的数 : " + stats.getMax());
    System.out.println("列表中最小的数 : " + stats.getMin());
    System.out.println("所有数之和 : " + stats.getSum());
    System.out.println("平均数 : " + stats.getAverage());
    输出结果:
    列表中最大的数 : 7
    列表中最小的数 : 2
    所有数之和 : 25
    平均数 : 3.5714285714285716
    

    并行(parallel)程序

    parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:

    List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
    // 获取空字符串的数量
    long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
    
    System.out.println(count);
    输出结果:
    2
    

    看上去并没有什么不同的,但是既然说并行处理的话,就找多个数据进行输出处理来进行尝试

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    numbers.parallelStream().forEach(System.out::println);
    输出结果:
    6
    3
    5
    4
    2
    1
    8
    7
    9
    结果显而易见,数序发生了错误,接下来打印线程信息来验证
    numbers.parallelStream() .forEach(num->System.out.println(Thread.currentThread().getName()+"->"+num));
    输出结果:
    ForkJoinPool.commonPool-worker-1->3
    ForkJoinPool.commonPool-worker-1->4
    ForkJoinPool.commonPool-worker-1->2
    ForkJoinPool.commonPool-worker-1->1
    ForkJoinPool.commonPool-worker-1->8
    ForkJoinPool.commonPool-worker-1->9
    ForkJoinPool.commonPool-worker-1->7
    ForkJoinPool.commonPool-worker-1->5
    main->6
    

    根据以上的输出结果可知,parallelStream是利用多线程来进行的,可以简化我们对并发操作的使用

    参考 圆圆同学的博客

    剩下的一些以后再做补充,如果有疑问或者看法请随时联系

  • 相关阅读:
    ASP.NET HttpRuntime.Cache缓存类使用总结
    ASP.NET MVC自定义AuthorizeAttribute篇知识点讲解—登录限制
    Echarts图表控件使用总结2(Line,Bar)—问题篇
    数据库查询实例(包含所有where条件例子)
    php file_get_contents读取大容量文件方法
    如何给mysql用户分配权限
    dedecms {dede:php}标签用法介绍
    js获取字符串最后一个字符代码
    CSS3选择器之学习笔记
    SQL中实现SPLIT函数几种方法
  • 原文地址:https://www.cnblogs.com/lovestart/p/11875468.html
Copyright © 2011-2022 走看看