• Java 8 新特性之——Stream


      Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

    一、简单介绍

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

    • <strong元素队列< strong="">元素是特定类型的对象,形成一个队列。 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是Java 8提出了的一种新的对集合对象功能的增强。它集合Lambda表达式,对集合提供了一些非常便利,高效的操作,使得代码具有非常高的可读性,优雅性!!

    二、Stream的操作流程

    Stream的所有操作分为三个阶段,【创建】>> 【中间操作】>> 【终端操作】

     1、Stream的创建

    • list.stream()

      List<String> list = Arrays.asList("1", "2", "3");

      Stream<String> stream = list.stream();

    • stream.of()
    //直接通过指定的元素创建
    Stream<String> stream = Stream.of("1", "2", "3");
    //通过数组Array
    String[] arrays = {"a", "b", "c"};
    Stream<String> stream = Stream.of(arrays);
    View Code

    2、Stream的中间操作

    Stream Operation Goal Input
    filter filter 方法用于通过设置的条件过滤出元素。 条件(返回布尔值)Predicate
    distnct 去除重复 --
    limit limit 方法用于获取指定数量的流 int值
    sorted sorted 方法用于对流进行排序 Comparator
    skip 跳过n个元素后再输出 --
    map map 方法用于映射每个元素到对应的结果 可以是一个功能 Function
    flatMap flatMap是将一个流中的每个值都转成一个个流,然后再将这些流扁平化成为一个流  --
    allMatch 用于检测是否全部都满足指定的参数行为,如果全部满足则返回true 条件(返回布尔值)Predicate
    reduce 对经过参数化操作后的集合进行进一步的运算 --
    counting 计算个数 int
    maxBy、minBy 计算最大值和最小值 int
    summingInt、summingLong、summingDouble 总和 int
    joining 字符串拼接 --
    groupingBy 分组 --

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    public class Test {
        public static void main(String[] args) {
            List<User> list = new ArrayList<User>();
            list.add(new User(1,"王正林",30,"带专"));
            list.add(new User(2,"阿正",19,"带专"));
            list.add(new User(3,"阿军",18,"带专"));
            list.add(new User(4,"小四",27,"带专"));
            list.add(new User(5,"曾虹",27,"本科"));
            list.add(new User(6,"王林",32,"本科"));
            list.add(new User(7,"歌颂",24,"本科"));
            list.add(new User(8,"阿华",26,"本科"));
            list.add(new User(9,"小巴",24,"成人高中"));
            list.add(new User(10,"阿水",20,"成人高中"));
            list.add(new User(11,"哦透",25,"成人高中"));
            list.add(new User(12,"巴氏",18,"成人高中"));
            //filter
            System.out.println("filter"+"获取学历是大专的人的名字");
            list.stream().filter(user->"带专".equals(user.getSchool())).forEach(user-> System.out.print(user.getName()+","));
            //distnct
            System.out.println();
            System.out.println("distnct"+"获取所有年龄不重复的user");
            List<Integer> userAgeList = list.stream().map(user -> user.getAge()).distinct().collect(Collectors.toList());
            System.out.print("userAgeList:"+userAgeList);
            //limit
            System.out.println();
            System.out.println("limit"+"查询年龄小于二十的前两位user名称");
            List<User> youngUser = list.stream().filter(user -> user.getAge() < 20).limit(2).collect(Collectors.toList());
            youngUser.forEach(user -> System.out.print(user.getName()+","));
            //sorted
            System.out.println();
            System.out.println("sorted"+"按年龄从小到大排序");
            list.stream().sorted((s1, s2) -> s2.getAge() - s1.getAge()).forEach(user -> System.out.print(user.getName()+","));
            //skip
            System.out.println();
            System.out.println("skip"+"跳过五个元素之后再输出");
            list.stream().skip(5).forEach(user -> System.out.print(user.getId()+","));
            //map
            System.out.println();
            System.out.println("skip"+"获取大专学历的user名字");
            List<String> daizhuanSchool = list.stream().filter(user -> "带专".equals(user.getSchool())).map(User::getName).collect(Collectors.toList());
            daizhuanSchool.forEach(user-> System.out.print(user+","));
            //allMatch
            System.out.println();
            System.out.println("skip"+"检测所有的user是否年龄都大于十六岁");
            boolean b = list.stream().allMatch(user -> user.getAge() > 16);
            System.out.println(b);
            //reduce
            System.out.println("reduce"+"获取本科user的年龄总和");
            Integer ageSum = list.stream().filter(user -> "本科".equals(user.getSchool())).map(User::getAge).reduce(Integer::sum).get();
            System.out.println(ageSum);
            //counting
            System.out.println("counting"+"获取所有user的总个数");
            long count = list.stream().count();
            System.out.println(count);
            //maxBy,minBy
            Integer maxAge = list.stream().collect(Collectors.maxBy((s1, s2) -> s1.getAge() - s2.getAge())).get().getAge();
            Integer minAge = list.stream().collect(Collectors.minBy((s1, s2) -> s1.getAge() - s2.getAge())).get().getAge();
            System.out.println("maxBy"+"年龄最大的user:"+maxAge);
            System.out.println("minBy"+"年龄最小的user:"+minAge);
            //summingInt
            Integer sumAge = list.stream().collect(Collectors.summingInt(User::getAge));
            System.out.println("summingInt"+"所有user年龄总和:"+sumAge);
            //joining
            String names = list.stream().map(User::getName).collect(Collectors.joining(","));
            System.out.println("joining"+"获取所有user的名称拼接起来:"+names);
            //groupingBy
            System.out.println("groupingBy"+"先按照大学分组再按照年龄进行分组");
            Map<String, Map<Integer, Long>> collect = list.stream().collect(Collectors.groupingBy(User::getSchool, Collectors.groupingBy(User::getAge, Collectors.counting())));
            System.out.println(collect);
        }
    }
    
    class User{
        private Integer id;       //主键id
        private String name;   //姓名
        private Integer age;   //年龄
        private String school; //学校
    
        public User(Integer id, String name, Integer age, String school) {
            this.id = id;
            this.name = name;
            this.age = age;
            this.school = school;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getSchool() {
            return school;
        }
    
        public void setSchool(String school) {
            this.school = school;
        }
    }
    View Code

     3、终端操作

    Stream Operation Goal Input Or Output
    forEach 遍历元素 其他操作
    count 统计元素个数 --
    collect 聚合操作 --
    • forEach遍历打印
    Stream.of("a", "b", "c").forEach(System.out::println);
    • count统计元素个数
    long count = Stream.of("a", "b", "c", "a").filter(x -> "a".equals(x)).count();//2
    • collect聚合
    // 1. 聚合转成List
    List<String> list1 = stream.collect(Collectors.toList());
    List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
    // 2. 聚合转成Set
    Set set1 = stream.collect(Collectors.toSet());
    Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
    // 3. 聚合转成String
    String str = stream.collect(Collectors.joining()).toString();

  • 相关阅读:
    HDU 5938 Four Operations 【贪心】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5935 Car 【模拟】 (2016年中国大学生程序设计竞赛(杭州))
    HDU 5934 Bomb 【图论缩点】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5933 ArcSoft's Office Rearrangement 【模拟】(2016年中国大学生程序设计竞赛(杭州))
    HDU 5929 Basic Data Structure 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)
    【转】LaTeX 符号命令大全
    HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)
    HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)
    数据结构之稀疏矩阵
    C++中引用(&)的用法和应用实例
  • 原文地址:https://www.cnblogs.com/yfstudy/p/13335060.html
Copyright © 2020-2023  润新知