四时宝库

程序员的知识宝库

学会使用JDK8的Stream让你的代码更简洁

从一个对象列表中获取某个属性的值的列表,

从一个对象列表中根据某个字段的最小/最大值获取其中的一个对象,

从一个对象列表中根据某个数字类型的字段进行累加,

将一个对象列表根据某个字段进行分组,变为Map,

……

相信以上很多很场景在你的编程生涯中都会遇到,那你是否还自己写for循环进行判断呢?来看看我是如何让代码更简洁!

JDK8 Stream流:让你的代码像流水一样流畅

介绍

Java Stream从入门到精通之简介(一)

@SpringBootTest(classes =
                Application.class,  
                webEnvironment = 
                SpringBootTest.WebEnvironment.RANDOM_PORT)
public class StreamIntroduction {
  /*一.Java Stream操作=======*/    
  //1. 外部迭代-----------------------
  /**     
  * Java 8 之前,在操作Java集合时,
  * 我们使用外部迭代。在外部迭代中,
  * 我们为每个循环使用for或,或者
  * 为集合获取一个迭代器,并按顺
  * 序处理集合的元素。下面的代码
  * 计算列表中所有奇数的平方和。
  * 它使用每个循环访问列表中的每
  * 个元素,然后使用if语句过滤奇数。
  * 然后计算平方,最后用sum变量
  * 存储平方的和。     
  */    
    @Test
    public void test00() {
        List<Integer> numbers = 
          Arrays.asList(1, 2, 3, 4, 5);       
        int sum = 0;        
        for (int n : numbers) {
            if (n % 2 == 1) {
                int square = n * n;                
                sum = sum + square;           
            }
        }
        System.out.println(sum);    
    }
    //2. 内部迭代----------------------
   /**     
   * 在上面的代码中,我们没有使用
   * loop语句来遍历列表。我们通过
   * 流在内部执行循环。对于奇整数
   * 的计算,我们使用lambda表达式。
   * 我们首先做过滤器, 然后映射,
   * 然后减少。    
   */    
    @Test
    public void test01() {
        List<Integer> numbers = 
                Arrays.asList(1, 2, 3, 4, 5);        
        int sum = numbers.stream()
      )//过滤(后面会讲到)
                .filter(n -> n % 2  == 1                
                .map(n  -> n * n)//映射
                //累加          
                .reduce(0, Integer::sum);     
      System.out.println(sum);    
    }
    //3.序列-------------------------
    /**     
    * 外部迭代通常意味着顺序代码。
    * 顺序代码只能由一个线程执行。
    * 流被设计成并行处理元素。    
    * 下面的代码并行计算列表中奇
    * 数的平方和。我们所做的只是
    * 将stream()替换为parallelStream()。    
    */    
    @Test
    public void test02() {
        List<Integer> numbers = 
                  Arrays.asList(1, 2, 3, 4, 5);        
        int sum = numbers.parallelStream()
                .filter(n -> n % 2  == 1)
                .map(n  -> n * n)
                .reduce(0, Integer::sum);        
      System.out.println(sum);    
    }
    //4. 命令式和函数式----------- 
    /**     
    * 在命令式编程中,我们不仅控制做
    * 什么,而且控制如何做。例如,
    * 在使用命令式编程对列表中的整数
    * 进行求和时。     
    * 我们必须决定如何迭代列表中的每
    * 个元素。我们可以使用for循环,
    * for-each循环,或者我们可以从
    * list中获得一个迭代器对象并
    * 使用while循环。     
    * 然后我们还要计算和。在声明式
    * 编程中,我们只需要告诉要做什么,
    * 系统本身如何处理这部分。
    * 集合支持命令式编程,
    * 而流支持声明式编程。     
    * StreamIntroduction API通过
    * 使用lambda表达式支持函数式编程。
    * 我们想对流元素执行的操作通常是
    * 通过传递一个lambda表达式来完成的。     
    * 流上的操作生成不修改数据源的
    * 结果(peek除外)。     
    */    
    //5. 中间操作终端操作-------------
    /**     
    * 流支持两种类型的操作:     
    *  中间操作(惰性操作):延迟操作
    * 在流上调用急于操作之前不会处理
    * 元素。指的是操作最终不会产生新的集合。     
    *  终端操作(即时操作):一个流上的
    * 中间操作会产生另一个流。指的是操作
    * 会产生新的集合。     
    * Streams链接操作以创建流管道。
    * 在下面的代码中,filter()和map()都是
    * 惰性操作。而reduce()是即时操作。     
    */    
    @Test
    public void test03() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);        
        int sum = numbers.parallelStream()
                .filter(n -> n % 2  == 1)
                .map(n  -> n * n)
                .reduce(0, Integer::sum);        
        System.out.println(sum);    
    }
    /*二.Java Stream API ========*/    
    /**     
    * Stream相关的接口和类在java.util包
    * 中。AutoCloseable接口来自
    * java.lang包。所有Stream接口都
    * 继承自BaseStream接口,     
    * 而BaseStream接口继承自
    * AutoCloseable接口。     
    * AutoCloseable     
    *  |     
    *  +--BaseStream     
    *      |     
    *      +--IntStream     
    *      |     
    *      +--LongStream     
    *      |     
    *      +--DoubleStream     
    *      |     
    *      +--Stream<T>     
    *  如果Stream使用集合作为其数据源,
    * 并且集合不需要关闭。     
    * 如果Stream基于可关闭的数据源
    * (如文件I/O通道),我们可以使用
    * try-with-resources语句创建Stream,
    * 使其自动关闭。     
    * 1. BaseStream     
    *  BaseStream接口定义了所有
    * Stream通用的所有方法。     
    *  -- Iterator<T> Iterator() 终端操作,
    * 返回流的迭代器。     
    *  -- sequential() 中间操作,
    * 返回一个串行流。如果流已经
    * 是串行,它就返回自己。
    * 它将并行流转换为顺序流。     
    *  -- parallel() 中间操作,
    * 返回并行流。如果流已经是
    * 并行的,它就返回自己。
    * 它将并行流转换为顺序流。     
    *  -- boolean isParallel() 如果流
    * 是并行的,返回true,否则返回
    * false。在调用终端流操作方法
    * 之后调用此方法可能会产生不
    * 可预测的结果。     
    *  -- unordered() 中间操作,
    * 返回流的无序版本。如果流已经
    * 是无序的,它将返回自己。     
    * 2.Stream     
    *      Stream<T>接口表示元素类
    * 型为T的流。Stream<Student>
    * 表示学生对象流。Stream<T>接口
    * 包含filter()、map()、reduce()、     
    *  collect()、max()、min()等方法。
    * 在使用基本类型时,我们可以使用
    * 三个专门的流接口,即IntStream、
    * LongStream和DoubleStream。     
    *  这些接口提供了处理基本值的方法。
    对于其他基本类型,如float、short、
    * byte,我们仍然可以使用这三种专用
    * 流接口。     
    *  在下面的代码中,我们将使用stream
    * 计算列表中所有奇数的平方和。     
    *  我们将使用以下步骤进行计算。     
    *  2.1 创建Stream     
    *      集合接口中的stream()方法返回
   * 一个顺序流。在这种情况下,
   * 集合充当数据源。下面的代码创建了
   * 一个列表<Integer>,     
   *      并从列表中获得一个流<Integer>:     
   *      List<Integer>  numbersList = Arrays.asList(1, 2, 3, 4, 5);     
   *      Stream<Integer> numbersStream  = numbersList.stream();     
   *  2.2 过滤Stream     
   *      Stream<T> filter()使用指定谓词返回
   * true时来保留流中的元素。下面的语句得到了一个奇数流:     
   *      Stream<Integer> oddNumbersStream= 
   * numbersStream.filter(n -> n % 2 == 1);     
   *  2.3 映射Stream     
   *      Stream<T> map()使用一个函数映射流
   * 中的每个元素并创建一个新的流。     
   *      Stream<Integer> aStream = 
   * stream.map(n -> n * n);// n = n * n     
   *  2.4 规约Stream     
   *      reduce(T identity, BinaryOperator<T> accumulator) 
   * 将流减少为单个值。接受一个初始值和一个二进制运算符<T>的     
   *      累加器作为参数。使用提供的初始值
   * 和关联累积函数对该流的元素执行减少,并返回减少的值。     
   *      int sum = aStream.reduce(0, (n1, n2) -> n1 + n2);     
   */    
    @Test
    public void test04() {
        List<Integer> numbers = 
          Arrays.asList(1, 2, 3, 4, 5);        
        int sum = numbers.stream()
                .filter(n -> n % 2  == 1)
                .map(n  -> n * n)
                .reduce(0, Integer::sum);        
        System.out.println(sum);    
    }
    /**     
    *  2.5 有序流与无序流     
    *      流可以是有序的,也可以是
    * 无序的。StreamIntroduction API
    * 可以将表示有序数据源(如列表或排序集)的
    * 有序流转换为无序流。     
    *      我们还可以通过应用排序中间操
    * 作将无序流转换为有序流。     
    */    
    @Test
    public void test05() {
        List<Integer> numbers = Arrays.asList(3,7,9,3,1,2,1, 2, 3, 4, 5);        
        numbers.stream()
                .filter(n -> n % 2  == 1)
                .sorted()
                .forEach(System.out::println);    
    }

}

Java Stream 顶级技巧(stream)

  • 1. 使用原始流以获得更好的性能

终于有人把Flink讲明白了,附阿里资深技术专家译Flink基础教程pdf

一、 Filnk简介和编程模型

Flink使用java语言开发,提供了scala编程的接口。使用java或者scala开发Flink是需要使用jdk8版本,如果使用Maven,maven版本需要使用3.0.4及以上。

Dataflows:


Java 流聚合(java的聚合)

要计算数字流上的和,max,min,average等,我们可以将非数字流映射到数值流类型(IntStream,LongStream或DoubleStream),然后使用专门的方法。

以下代码计算收入的总和。 mapToDouble()方法将 Stream<Employee> 转换为 DoubleStream 。对DoubleStream调用sum()方法。

Java中Stream简明使用教程(java中stream用法)

一、前言

都JDK15了,你还在使用java8?那好,你知道jdk8的Strean都有哪些用法吗...

大数据之Flink-数据转换(Transformation)

大数据之(Transformation)

1. 前言

Flink 应用程序结构就是如上图所示:

1、Source: 数据源,Flink 在流处理和批处理上的 source 大概有 4 类:基于本地集合的 source、基于文件的 source、基于网络套接字的 source、自定义的 source。自定义的 source 常见的有 Apache kafka、Amazon Kinesis Streams、RabbitMQ、Twitter Streaming API、Apache NiFi 等,当然你也可以定义自己的 source。

java基础知识2(java8常用Stream流操作)


概念:Stream是java8提出的一个新的概念,不是输入输出的Stream流,而是一种函数式编程方式在集合类上进行复杂的操作的工具,简言之就是,以内部迭代的方式处理集合数据的操作,内部迭代可以将更多的控制权交给集合类。Stream和Iterator的功能类似,只是Iterator是以外部的形式处理集合数据的操作。

玩转Java8Stream(五、并行Stream)

java8的并行Stream对开发者非常友好,非常容易实现并行计算。并行Stream底层使用ForkJoinTask实现Stream的并行处理,充分利用cpu的多核能力,Stream的API将底层复杂实现完全屏蔽了,开发者仅需调用一个方法即可实现并行计算,就是这么简单。

<< < 1 2 3 > >>
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接