zoukankan      html  css  js  c++  java
  • 5、转换Stream流

    1、概念

    转换Stream其实就是把一个Stream通过某些行为转换成一个新的Stream

    多个转换可以连接起来形成一个流水线,除非流水线上触发终止操作,否则转换操作不会执行任何的处理,而是在终止操作时候一次性全部处理,称为“惰性求值”。

    2、筛选与切片

    2.1、filter

    filter 对于Stream中包含的元素使用给定的过滤函数进行过滤操作,新生成的Stream只包含符合条件的元素

    image

    下面的代码就是过滤出年纪大于25岁的学生

            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(2, "tom", 25));
            studentList.add(new Student(2, "jack", 27));
            studentList.add(new Student(2, "rose", 22));
    
            List<Student> newList = studentList.stream().filter(x->x.getAge()>25).collect(Collectors.toList());
            System.out.println(newList);//[Student(id=2, name=jack, age=27)]
    

    2.2、limit

    limit 对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素

    image

    下面的代码就是过滤出前2个学生

            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(2, "tom", 25));
            studentList.add(new Student(2, "jack", 27));
            studentList.add(new Student(2, "rose", 22));
    
            List<Student> newList = studentList.stream().limit(2).collect(Collectors.toList());
            System.out.println(newList);//[Student(id=1, name=赵迪, age=23), Student(id=2, name=tom, age=25)]
    

    2.3、skip

    skip 跳过指定的个数,返回一个丢弃原Stream的前N个元素后剩下元素组成的新Stream,如果原Stream中包含的元素个数小于N,那么返回空Stream

    image

    下面的代码就是跳过前面2个学生

            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(2, "tom", 25));
            studentList.add(new Student(2, "jack", 27));
            studentList.add(new Student(2, "rose", 22));
    
            List<Student> newList = studentList.stream().skip(2).collect(Collectors.toList());
            System.out.println(newList);//[Student(id=2, name=jack, age=27), Student(id=2, name=rose, age=22)]
    

    2.4、distinct

    distinct 表示对stream中的元素进行去重操作,得到新的stream不存在重复的元素,去重的逻辑依赖元素的equals方法
    image

    下面的代码是去重学生,根据ID

            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(2, "tom", 25));
            studentList.add(new Student(2, "tom", 27));
            studentList.add(new Student(2, "rose", 22));
    
            List<Student> newList = studentList.stream().distinct().collect(Collectors.toList());
    

    3、映射

    SQL中,借助SELECT关键字后面添加需要的字段名称,可以仅输出我们需要的字段数据,而流式处理的映射操作也是实现这一目的,在java8的流式处理中,主要包含两类映射操作:mapflatMap

    3.1、map

    将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

    image

    下面的代码就是通过map将student的年纪映射出来

            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(2, "tom", 25));
            studentList.add(new Student(2, "tom", 27));
            studentList.add(new Student(2, "rose", 22));
    
            studentList.stream().map(x -> x.getAge()).collect(Collectors.toList());
            List<Integer> newList = studentList.stream().map(x -> x.getAge()).collect(Collectors.toList());
            System.out.println(newList);//[23, 25, 27, 22]
    

    3.2、flatMap

    与map类似,不同的是其每个元素转换得到的是Stream对象,会把子Stream中的元素压缩到父集合中,也就是说,将流中的每一个值都换成另一个流,然后把所有流连成一个流。

    image

    3.3、map和flatMap区别

    举例子说明

    有二箱鸡蛋,每箱5个,现在要把鸡蛋加工成煎蛋,然后分给学生。

    map做的事情:把二箱鸡蛋分别加工成煎蛋,还是放成原来的两箱,分给2组学生;

    flatMap做的事情:把二箱鸡蛋分别加工成煎蛋,然后放到一起【10个煎蛋】,分给10个学生;

    4、排序

    排序主要分为两种,第一种就是自然排序,第二种就是定制排序

    4.1、自然排序(java.lang.Comparable)

    Comparable接口强行对实现它的每个类的对象进行整体排序,这种排序被称为类的自然排序

    实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即 通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大 于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回 负整数,如果当前对象this等于形参对象obj,则返回零。

    实现Comparable接口的对象列表(和数组)可以通过 Collections.sortArrays.sort进行自动排序。实现此接口的对象可以用作有序映射中的键或有 序集合中的元素,无需指定比较器。

    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Student implements Comparable {
    
        private Integer id;
    
        private String name;
    
        private Integer age;
    
        @Override
        public int compareTo(Object o) {
            Student other = (Student) o;
            if (this.getAge() > other.getAge()) {
    
                return 1;
            } else if (this.getAge() < other.getAge()) {
                return -1;
            }
            return 0;
        }
    }
    
    

    上述代码中,Student类实现了Comparable接口,并且实现了comparaTo方法

    public class StreamDemo01 {
        public static void main(String[] args) {
            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(3, "tom", 25));
            studentList.add(new Student(2, "tom", 27));
            studentList.add(new Student(2, "rose", 22));
            List<Student> list = studentList.stream().sorted().collect(Collectors.toList());
            System.out.println(list);
        }
    }
    

    上述代码按照age进行由低到高排序,结果如下

    [Student(id=2, name=rose, age=22), Student(id=1, name=赵迪, age=23), Student(id=3, name=tom, age=25), Student(id=2, name=tom, age=27)]
    

    4.2、定制排序(java.util.Comparator)

    当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序,强行对多个对象进行整体排序的比较。

    重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返 回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示 o1小于o2

    可以将Comparator传递给sort方法(如 Collections.sort Arrays.sort), 从而允许在排序顺序上实现精确控制

    public class StreamDemo01 {
        public static void main(String[] args) {
            List<Student> studentList = new ArrayList<>();
            studentList.add(new Student(1, "赵迪", 23));
            studentList.add(new Student(3, "tom", 25));
            studentList.add(new Student(2, "tom", 27));
            studentList.add(new Student(2, "rose", 22));
            Comparator<Student> comparator = new Comparator<Student>() {
                @Override
                public int compare(Student o1, Student o2) {
                    return o1.getId() - o2.getId();
                }
            };
            List<Student> list = studentList.stream().sorted(comparator).collect(Collectors.toList());
            System.out.println(list);
        }
    

    上述代码中,自定义比较器comparator,传递给sorted,按照id从小到大排序,结果如下

    [Student(id=1, name=赵迪, age=23), Student(id=2, name=tom, age=27), Student(id=2, name=rose, age=22), Student(id=3, name=tom, age=25)]
    
    
    一个小小的程序员
  • 相关阅读:
    设计模式总结
    设计模式之工厂
    C#
    UML画图总结
    UML视频总结
    类图
    读取文件信息
    HMAC算法加密
    SHA_1计算消息摘要
    获取指定长度的随机字符串
  • 原文地址:https://www.cnblogs.com/zhaod/p/13437171.html
Copyright © 2011-2022 走看看