JDK1.8新特性Stream流式操作,简化遍历操作

一. 前言

随着Java的发展,越来越多的企业开始使用JDK1.8 版本。JDK1.8 是自 JDK1.5之后最重要的版本,这个版本包含语言、编译器、库、工具、JVM等方面的十多个新特性。本次文章将着重学习Stream

StreamJDK1.8 中处理集合的关键抽象概念,LambdaStreamJDK1.8新增的函数式编程最有亮点的特性了,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

+--------------------+       +------+   +------+   +---+   +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+       +------+   +------+   +---+   +-------+

简而言之,Stream API提供了一种高效且易于使用的处理数据的方式。

二. 什么是Stream

Stream 翻译称为 “流”,是 Java8 的新特性之一。 Stream 将要处理的元素看作是流,这时可以借助 Stream API 对流中的元素进行中间操作,比如:筛选、排序、排序等。

1. 特点

  • 不是数据结构,不会保存数据,只会操作数据,Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
  • 不会改变数据源,它会将操作后的数据保存到另外一个对象中。
  • 延迟执行,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。

2. 三个步骤

  • 1、创建Stream: 从数据源中获取一个流,这个数据源可以是集合、数组。
  • 2、中间操作:操作链,可以对流进行数据处理。
  • 3、终止操作:执行终止操作,才会执行中间操作的操作链,终端操作结束后流无法再次使用,会产生一个新的结果。
    在这里插入图片描述

3. Stream常见用法

在这里插入图片描述

三. 关于Stream API

1. Stream API分类

Stream 操作分为中间操作或者终止操作两种,终止操作返回一特定类型的计算结果,而中间操作返回Stream本身,Stream 的操作类型具体分类如下:
img

解释:

  • 无状态:指元素的处理不受之前元素的影响;

  • 有状态:指该操作只有拿到所有元素之后才能继续下去。

  • 非短路操作:指必须处理所有元素才能得到最终结果;

  • 短路操作:指遇到某些符合条件的元素就可以得到最终结果,如 A || B,只要A为true,则无需判断B的结果。

2. 如何使用Stream流?

使用Stream流分为三步。

  • 创建Stream

    一个数据源(如:集合、数组),获取一个Stream流。

  • 中间操作

    一个中间操作链,对数据源(如:集合、数组)的数据进行处理。

  • 终止操作

    一个终止操作,执行中间操作链,并产生一个计算结果。

3. Stream的中间操作和结束操作

  • 中间操作

    filter: 过滤流,过滤流中的元素,返回一个符合条件的Stream

    map: 转换流,将一种类型的流转换为另外一种流。(mapToInt、mapToLong、mapToDouble 返回int、long、double基本类型对应的Stream)

    flatMap: 简单的说,就是一个或多个流合并成一个新流。(flatMapToInt、flatMapToLong、flatMapToDouble 返回对应的IntStream、LongStream、DoubleStream流。)

    distinct: 返回去重的Stream。

    sorted: 返回一个排序的Stream。

    peek: 主要用来查看流中元素的数据状态。

    limit: 返回前n个元素数据组成的Stream。属于短路操作

    skip: 返回第n个元素后面数据组成的Stream。

  • 终止操作

    forEach: 循环操作Stream中数据。

    toArray: 返回流中元素对应的数组对象。

    reduce: 聚合操作,用来做统计,将流中元素反复结合起来统计计算,得到一个值.。

    collect: 聚合操作,封装目标数据,将流转换为其他形式接收,如: List、Set、Map、Array。

    min、max、count: 聚合操作,最小值,最大值,总数量。

    anyMatch: 短路操作,有一个符合条件返回true。

    allMatch: 所有数据都符合条件返回true。

    noneMatch: 所有数据都不符合条件返回true。

    findFirst: 短路操作,获取第一个元素。

    findAny: 短路操作,获取任一元素。

    forEachOrdered: 暗元素顺序执行循环操作。


四. Stream流的具体用法

在 Java 8 中, 集合接口有两个方法来生成流:

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

1. stream和parallelStream的简单区分:

stream是顺序流,由主线程按顺序对流执行操作。

parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如筛选集合中的奇数,两者的处理不同之处:
在这里插入图片描述
如果流中的数据量足够大,并行流可以加快处理速度。

除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流:

Optional<Integer> findFirst = list.stream().parallel().filter(x->x>6).findFirst();

2. 流的常用创建方式

/**
 * stream,获取各种集合的stream流
 */
@Test
public void testCollectionStream(){
    //List集合  
    List<String> stringList = new ArrayList<>();
    //Set集合
    Set<String> stringSet = new HashSet<>();
    //Map集合
    Map<String,Object> stringObjectMap = new HashMap<>();
    //数组
    String[] stringArray = {"张三三","李四","王五","王五","赵八",};

    //通过list获取stream流
    Stream<String> streamList = stringList.stream();
    //通过set获取stream流
    Stream<String> streamSet = stringSet.stream();
    //通过map获取stream流
    Stream<String> streamMap = stringObjectMap.keySet().stream();
    //通过array获取stream流
    Stream<String> streamArray1 = Stream.of(stringArray);
}

3. 构造流的几种常见方法

@Test
public void testCollectionStream(){
   // 1. Individual values
  Stream stream = Stream.of("a", "b", "c");
  
  // 2. Arrays
  String[] strArray = new String[]{"a", "b", "c"};
  stream = Stream.of(strArray);
  stream = Arrays.stream(strArray);
  
  // 3. Collections
  List<String> list = Arrays.asList(strArray);
  stream = list.stream();
  
}

五. Stream在代码中的使用方式

关于Stream的常见操作方式,主要分为两大类: 中间操作和终止操作 ,接下来就通过这两大分类,讲解下具体的语法用法。

1. 流的中间操作

1.1 筛选过滤

  • filter:过滤流中的某些元素

       /**
         * filter 方法 , 返回符合过滤条件的值
         */
        @Test
        public void testFilter() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.stream().filter(e -> e.contains("张")).forEach(System.out::println);
        }
    

    • filter多个过滤筛选条件
       /**
      * list集合stream流式操作
      */
     @Test
     public void testStreamList() {
         List<String> list = new ArrayList<>();
         list.add("张三三");
         list.add("李四");
         list.add("王五");
         list.add("孙七");
         list.add("赵八");
         list.stream().filter(e -> e.startsWith("张")) //过滤所有姓张的人
                 .filter(e -> e.length() == 3) //过滤所有姓名是3个字的人
                 .forEach(System.out::println); //遍历打印,System.out::println表明System.out调用println打印方法
     }
    
  • limit(n):获取前n个元素

     /**
         * limit 方法 ,返回前n个元素数据值组成的Stream。
         */
        @Test
        public void testLimit() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            list.stream().limit(3).forEach(System.out::println); //取前3个
        }
    
  • skip(n):跳过n元素,配合limit(n)可实现分页

     /**
         * skip方法 ,跳过前n个元素的中间流操作,返回剩下的值。
         */
        @Test
        public void testSkip() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            //list.stream().skip(3).forEach(System.out::println); //跳过前3个
            list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit实现分页
        }
    
  • distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素

     /**
         * distinct, 返回去重的Stream
         */
        @Test
        public void testDistinct() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
        }
    

1.2 排序

  • sorted():自然排序,流中元素需实现Comparable接口

     /**
         * sorted: 返回一个排序的Stream
         */
        @Test
        public void testSorted() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
        }
    
  • sorted(Comparator com):定制排序,自定义Comparator排序器

1.3 映射

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
/**
    * 遍历map集合,截取substring(2)开始的值
    */
   @Test
   public void testMap() {
       List<String> list = new ArrayList<>();
       list.add("张三三");
       list.add("李四");
       list.add("王五");
       list.add("孙七");
       list.add("赵八");
       list.add("王二麻子");
       Stream<String> stream = list.stream().map(e -> e.substring(2));
       stream.forEach(System.out::println);
   }
  • forEach:ForEach流式遍历集合

      /**
         * forEach, ForEach流式遍历list集合
         */
        @Test
        public void testForEach() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.stream().forEach(System.out::println);
        }
    

2. 流的终止操作

2.1 匹配、聚合操作

  • allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false

     /**
         * allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
         */
        @Test
        public void testAllMatch() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            boolean b = list.stream()
                    .allMatch(e -> list.size() > 8);
            System.out.println("b = " + b);
        }
    
  • noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false

        /**
         * noneMatch: 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
         */
        @Test
        public void testNoneMatch() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            boolean b = list.stream().noneMatch(e->e.equals("张三"));
            System.out.println("b = " + b);
        }
    
  • anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false

    /**
         * anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
         */
        @Test
        public void testAnyMatch() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            boolean b = list.stream().anyMatch(e -> e.equals("王二麻子"));
            System.out.println("b = " + b);
        }
    
  • findFirst:返回流中第一个元素

     /**
         * findFirst:返回流中第一个元素
         */
        @Test
        public void testFindFirsth() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            Optional<String> first = list.stream().findFirst();
            System.out.println("first = " + first.get());
        }
    
  • findAny:返回流中的任意元素

        /**
         * findAny:返回流中第一个元素
         */
        @Test
        public void testFindAny() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("李四");
            list.add("王五");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            Optional<String> any = list.stream().findAny();
            System.out.println("any = " + any.get());
        }
    
  • count:返回流中元素的总个数

     /**
         * count,获取List集合的长度
         */
        @Test
        public void testCount() {
            List<String> list = new ArrayList<>();
            list.add("张三三");
            list.add("李四");
            list.add("王五");
            list.add("孙七");
            list.add("赵八");
            list.add("王二麻子");
            long count = list.stream().count();
            System.out.println("count = " + count);
            int size = list.size();
            System.out.println("size = " + size);
        }
    
  • max:返回流中元素最大值

    /**
         * max:返回流中元素最大值
         */
        @Test
        public void testMax() {
            List<Integer> list = new ArrayList<>();
            list.add(11);
            list.add(22);
            list.add(33);
            list.add(44);
            list.add(55);
            list.add(66);
            list.add(77);
            list.add(88);
            Integer integer = list.stream().max(Integer::compareTo).get();
            System.out.println("integer = " + integer);
        }
    
  • min:返回流中元素最小值

    /**
     * min:返回流中元素最小值
     */
    @Test
    public void testMin() {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().min(Integer::compareTo).get();
        System.out.println("integer = " + integer);
        list.stream().limit(1).limit(2).distinct().skip(3).filter(f -> f.equals(55)).forEach(System.out::println);
    }
    
  • collect:聚合操作,封装目标数据,将流转换为其他形式接收,List、Map、Set等

   /**
     * collect,将流转化为List集合,然后遍历集合
     */
    @Test
    public void testCollect() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        List<String> collect = list.stream().skip(3).limit(2).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }
  • reduce:聚合操作,用来做统计,将流中元素反复结合起来统计计算,得到一个值
    /**
     * reduce: 聚合操作,用来做统计,将流中元素反复结合起来统计计算,得到一个值.
     */
    @Test
    public void testReduce() {
        //1.求集合元素只和
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
        Integer result = stream.reduce(0, Integer::sum);
        System.out.println(result);

        //2.求和
        Stream<Integer> stream1 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream1.reduce((i, j) -> i + j).ifPresent(System.out::println);

        //3.求最大值
        Stream<Integer> stream2 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream2.reduce(Integer::max).ifPresent(System.out::println);

        //4.求最小值
        Stream<Integer> stream3 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream3.reduce(Integer::min).ifPresent(System.out::println);

        //5.做逻辑
        Stream<Integer> stream4 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream4.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);

        //6.求逻辑求乘机
        Stream<Integer> stream5 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        int result2 = stream5.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);
        Optional.of(result2).ifPresent(System.out::println);
    }

2.2 Collector 工具库:Collectors

  • Collectors

    Student s1 = new Student("aa", 10,1);
    Student s2 = new Student("bb", 20,2);
    Student s3 = new Student("cc", 10,3);
    List<Student> list = Arrays.asList(s1, s2, s3);
      
    //stream转成list
    List<Integer> ageList = list.stream().map(Student::getAge).collect(Collectors.toList()); // [10, 20, 10]
      
    //stream转成set
    Set<Integer> ageSet = list.stream().map(Student::getAge).collect(Collectors.toSet()); // [20, 10]
      
    //stream转成map,注:key不能相同,否则报错
    Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge)); // {cc=10, bb=20, aa=10}
      
    //字符串分隔符连接
    String joinName = list.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc)
      
    //聚合操作
    //1.学生总数
    Long count = list.stream().collect(Collectors.counting()); // 3
    //2.最大年龄 (最小的minBy同理)
    Integer maxAge = list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 20
    //3.所有人的年龄
    Integer sumAge = list.stream().collect(Collectors.summingInt(Student::getAge)); // 40
    //4.平均年龄
    Double averageAge = list.stream().collect(Collectors.averagingDouble(Student::getAge)); // 13.333333333333334
    // 带上以上所有方法
    DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Student::getAge));
    System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage());
      
    //分组
    Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge));
    //多重分组,先根据类型分再根据年龄分
    Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge)));
      
    //分区
    //分成两部分,一部分大于10岁,一部分小于等于10岁
    Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));
      
    //规约
    Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); //40  
    

六、Stream操作代码

为了方便小伙伴们看到这篇博客时,学习的更加轻松,这里贴出源码,小伙伴们学习是可贴到IDEA运行查看Stream过滤筛选的结果,以此对Stream的流式操作更加熟悉。

package com.java8.example.chapter3;

import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @desc: Stream流式操作
 * @author: cao_wencao
 * @date: 2020-09-17 15:24
 */
public class TestStreamList {

    /**
     * list集合stream流式操作
     */
    @Test
    public void testStreamList() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.stream().filter(e -> e.startsWith("张")) //过滤所有姓张的人
                .filter(e -> e.length() == 3) //过滤所有姓名是3个字的人
                .forEach(System.out::println); //遍历打印,System.out::println表明System.out调用println打印方法
    }

    /**
     * stream,获取各种集合的stream流
     */
    @Test
    public void testCollectionStream() {
        List<String> stringList = new ArrayList<>();
        Set<String> stringSet = new HashSet<>();
        Map<String, Object> stringObjectMap = new HashMap<>();
        String[] stringArray = {"张三三", "李四", "王五", "王五", "赵八",};

        //通过list获取stream流
        Stream<String> streamList = stringList.stream();
        //通过set获取stream流
        Stream<String> streamSet = stringSet.stream();
        //通过map获取stream流
        Stream<String> streamMap = stringObjectMap.keySet().stream();
        //通过array获取stream流
        Stream<String> streamArray1 = Stream.of(stringArray);

    }

    /**
     * forEach, ForEach流式遍历list集合
     */
    @Test
    public void testForEach() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.stream().forEach(System.out::println);
    }

    /**
     * filter 方法 , 返回符合过滤条件的值
     */
    @Test
    public void testFilter() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.stream().filter(e -> e.contains("张")).forEach(System.out::println);
    }

    /**
     * 遍历map集合,截取substring(2)开始的值
     */
    @Test
    public void testMap() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        Stream<String> stream = list.stream().map(e -> e.substring(2));
        stream.forEach(System.out::println);
    }

    /**
     * count,获取List集合的长度
     */
    @Test
    public void testCount() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        long count = list.stream().count();
        System.out.println("count = " + count);
        int size = list.size();
        System.out.println("size = " + size);
    }

    /**
     * limit 方法 ,返回前n个元素数据值组成的Stream。
     */
    @Test
    public void testLimit() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        list.stream().limit(3).forEach(System.out::println); //取前3个
    }

    /**
     * skip方法 ,跳过前n个元素的中间流操作,返回剩下的值。
     */
    @Test
    public void testSkip() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        //list.stream().skip(3).forEach(System.out::println); //跳过前3个
        list.stream().skip(3).limit(2).forEach(System.out::println); //skip+limit实现分页
    }

    /**
     * collect,将流转化为集合
     */
    @Test
    public void testCollect() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        List<String> collect = list.stream().skip(3).limit(2).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

   /**
     * reduce: 聚合操作,用来做统计,将流中元素反复结合起来统计计算,得到一个值.
     */
    @Test
    public void testReduce() {
        //1.求集合元素只和
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8});
        Integer result = stream.reduce(0, Integer::sum);
        System.out.println(result);

        //2.求和
        Stream<Integer> stream1 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream1.reduce((i, j) -> i + j).ifPresent(System.out::println);

        //3.求最大值
        Stream<Integer> stream2 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream2.reduce(Integer::max).ifPresent(System.out::println);

        //4.求最小值
        Stream<Integer> stream3 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream3.reduce(Integer::min).ifPresent(System.out::println);

        //5.做逻辑
        Stream<Integer> stream4 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        stream4.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);

        //6.求逻辑求乘机
        Stream<Integer> stream5 = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        int result2 = stream5.filter(i -> i % 2 == 0).reduce(1, (i, j) -> i * j);
        Optional.of(result2).ifPresent(System.out::println);
    }

    /**
     * distinct, 返回去重的Stream
     */
    @Test
    public void testDistinct() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        list.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * sorted: 返回一个排序的Stream
     */
    @Test
    public void testSorted() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        list.stream().distinct().sorted().collect(Collectors.toList()).forEach(System.out::println);
    }

    /**
     * anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
     */
    @Test
    public void testAnyMatch() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        boolean b = list.stream().anyMatch(e -> e.equals("王二麻子"));
        System.out.println("b = " + b);
    }

    /**
     * noneMatch: 接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
     */
    @Test
    public void testNoneMatch() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        boolean b = list.stream().noneMatch(e->e.equals("张三"));
        System.out.println("b = " + b);
    }

    /**
     * allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
     */
    @Test
    public void testAllMatch() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        boolean b = list.stream()
                .allMatch(e -> list.size() > 8);
        System.out.println("b = " + b);
    }

    /**
     * findFirst:返回流中第一个元素
     */
    @Test
    public void testFindFirsth() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        Optional<String> first = list.stream().findFirst();
        System.out.println("first = " + first.get());
    }


    /**
     * findAny:返回流中第一个元素
     */
    @Test
    public void testFindAny() {
        List<String> list = new ArrayList<>();
        list.add("张三三");
        list.add("李四");
        list.add("李四");
        list.add("王五");
        list.add("王五");
        list.add("孙七");
        list.add("赵八");
        list.add("王二麻子");
        Optional<String> any = list.stream().findAny();
        System.out.println("any = " + any.get());
    }

    /**
     * max:返回流中元素最大值
     */
    @Test
    public void testMax() {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().max(Integer::compareTo).get();
        System.out.println("integer = " + integer);
    }

    /**
     * min:返回流中元素最小值
     */
    @Test
    public void testMin() {
        List<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(22);
        list.add(33);
        list.add(44);
        list.add(55);
        list.add(66);
        list.add(77);
        list.add(88);
        Integer integer = list.stream().min(Integer::compareTo).get();
        System.out.println("integer = " + integer);
        list.stream().limit(1).limit(2).distinct().skip(3).filter(f -> f.equals(55)).forEach(System.out::println);
    }
}

总结

以上就是对于JDK1.8中Stream流式计算的一个简单介绍,关于JDK1.8中的新特性,用法远远不止这些,这篇文章只作为一个简单的入门使用,更深层次的理解请后续关注JDK1.8系列的文章。

  • 74
    点赞
  • 319
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thinkingcao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值