美文网首页职业生涯规划Java架构技术进阶
Stream流的这些操作,你得知道,对你工作有很大帮助

Stream流的这些操作,你得知道,对你工作有很大帮助

作者: 傻姑不傻 | 来源:发表于2020-10-28 17:57 被阅读0次

    Stream流

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

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

    Stream流操作的三个步骤:

    1. 创建Stream

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

    2. 中间操作

      一个中间操作链,对数据源的数据进行处理

    3. 终止操作

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

    创建Stream步骤:

    • 通过Collection系列集合提供的顺序流stream()或并行流parallelStream()
    • 通过Arrays中的静态方法stream()获取数据流
    • 通过Stream类中的静态方法of()

    代码实例

    package com.ysh.review01_Stream;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StreamTest01 {
        public static void main(String[] args) {
            //第一种方式:通过集合中的stream()方法创建Stream
            List<String> list= Arrays.asList("红太狼","灰太狼","喜羊羊");
            Stream<String> stream=list.stream();
            //通过集合中的parallelStream方法创建
            Stream<String> stream2 = list.parallelStream();
            //第二种方式:通过java.util.Arrays下的静态方法stream创建Stream
            Integer[] integer=new Integer[]{1,2,4};
            //这里需要注意的是Arrays中的stream方法里面的参数需要一个数组,且数组的类型是一个引用类型或者是一个包装类
            Stream<Integer> stream3 = Arrays.stream(integer);
            //第三种方式:通过Stream中的of方法,实际上这种方式创建Stream实际上间接的通过调用Arrays中的stream()静态方法
            Stream<String> stream4=Stream.of("a","b","c");
        }
    }
    
    

    Stream的中间操作

    筛选和切片

    filter:过滤器

    package com.ysh.review01_Stream;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StramTest02 {
        public static void main(String[] args) {
            Employee employee01=new Employee("yang","hui",29);
            Employee employee02=new Employee("yang","hui",49);
            Employee employee03=new Employee("yang","hui",9);
            Employee employee04=new Employee("yang","hui",89);
            Employee employee05=new Employee("yang","hui",89);
            Employee employee06=new Employee("yang","hui",89);
            List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
            //创建Stream
            Stream<Employee> stream1 = list.stream();
            //对stream1流进行过滤
            Stream<Employee> s = stream1.filter((e) -> {
                System.out.println("---------------filter------------");
                //过滤掉年龄小于19
                return e.getAge() >= 19;
            });
            s.forEach((e-> System.out.println(e)));
        }
    }
    class Employee {
        private String id;
        private String name;
        private int age;
    
        public Employee() {
    
        }
    
        public Employee(String id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Employee employee = (Employee) o;
            return age == employee.age &&
                    id.equals(employee.id) &&
                    name.equals(employee.name);
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    

    运行结果

    skip(n):指跳过Stream中存储的前n条数据(包含第n条数据),返回后n条数据,如果n大于Stream中所有元素的个数,则返回空;(Employee类如上)

    package com.ysh.review01_Stream;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StramTest02 {
        public static void main(String[] args) {
            Employee employee01=new Employee("yang","hui",9);
            Employee employee02=new Employee("yang","hui",49);
            Employee employee03=new Employee("yang","hui",9);
            Employee employee04=new Employee("yang","hui",89);
            Employee employee05=new Employee("yang","hui",89);
            Employee employee06=new Employee("yang","hui",89);
            List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
            //创建Stream
            Stream<Employee> stream1 = list.stream();
            //对stream1流进行过滤
            Stream<Employee> s = stream1.filter((e) -> {
                System.out.println("---------------filter------------");
                //过滤掉年龄小于19
                return e.getAge() >= 19;
            }).skip(2);
            //s=s.skip(5);
            s.forEach((e-> System.out.println(e)));
        }
    }
    
    

    运行截图

    distinct:筛选重复的元素,通过流生产元素的hashCode()和equals去除重复元素;

    package com.ysh.review01_Stream;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Stream;
    
    public class StramTest02 {
        public static void main(String[] args) {
            Employee employee01=new Employee("yang","hui",9);
            Employee employee02=new Employee("yang","hui",49);
            Employee employee03=new Employee("yang","hui",9);
            Employee employee04=new Employee("yang","hui",89);
            Employee employee05=new Employee("yang","hui",89);
            Employee employee06=new Employee("yang","hui",89);
            List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
            //创建Stream
            Stream<Employee> stream1 = list.stream();
            //对stream1流进行过滤
            Stream<Employee> s = stream1.filter((e) -> {
                System.out.println("---------------filter------------");
                //过滤掉年龄小于19
                return e.getAge() >= 19;
            }).skip(2).distinct();
            //s=s.skip(5);
            s.forEach((e-> System.out.println(e)));
        }
    }
    
    

    运行截图:

    排序

    sorted(Comparable)–自然排序

    package com.ysh.review01_Stream;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StreamTest03 {
        public static void main(String[] args) {
            List<String> list= Arrays.asList("c","bbb","abc","bbbb");
            Stream<String> stream = list.stream();
            //即通过调用String方法中CompareTo,通过一个一个的比较字符的ASCLL值,首先比较首字符的ASCLL大小,相同的话再比较下一个
            stream= stream.sorted();
            stream.forEach(System.out::println);
        }
    }
    
    

    sorted(Comparator)–定制排序

    package com.ysh.review01_Stream;
    
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Stream;
    
    public class StramTest02 {
        public static void main(String[] args) {
            Employee employee01=new Employee("yang","哈哈",19);
            Employee employee02=new Employee("yang","hui",49);
            Employee employee03=new Employee("yang","hui",79);
            Employee employee04=new Employee("yang","呵呵呵",79);
            Employee employee05=new Employee("yang","hui",39);
            Employee employee06=new Employee("yang","hui",29);
            List<Employee> list= Arrays.asList(employee01,employee02,employee03,employee04,employee05,employee06);
            //创建Stream
            Stream<Employee> stream1 = list.stream();
            //对stream1流进行过滤
            Stream<Employee> s = stream1.filter((e) -> {
                System.out.println("---------------filter------------");
                //过滤掉年龄小于19
                return e.getAge() >= 19;
            });
            //s=s.skip(5);
            /*此处可以使用Lambda表达式,即s.sorted((o1,o2)->{
                                  //升序排序,如果年龄相同,则按照姓名的长度排序 
                                             if (o1.getAge()==o2.getAge()){
                                                return o1.getName().length()-o2.getName().length();
                                         }
                                          //按照年龄升序排序
                                          return o1.getAge()-o2.getAge();
    
                              })
    
             */
            s=s.sorted(new Comparator<Employee>() {
                @Override
                public int compare(Employee o1, Employee o2) {
                    //升序排序,如果年龄相同,则按照姓名的长度排序
                    if (o1.getAge()==o2.getAge()){
                        return o1.getName().length()-o2.getName().length();
                    }
                    //按照年龄升序排序
                    return o1.getAge()-o2.getAge();
                }
            });
            s.forEach((e-> System.out.println(e)));
        }
    }
    
    

    Stream中的map和flatMap方法:

    • 流中的每一个数据,当做map方法的参数(接口),接口中抽象方法的参数,进行制定操作,最终得到一个结果,最后所有的结果返回去成为一个流
    • 流中的每一个数据当作参数,进行操作,得到的结果必须是一个流,最终会结合成一个流返回
    package com.ysh.review01_Stream;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StreamTest04 {
        public static void main(String[] args) {
            Stream<String> stream=Stream.of("aaa","bbbb","ccccc");
            //map方法是每一个数据当作一个流,即以上{aaa}、{bbbb}、{ccccc}各是一个Stream<Character>流集合,即达到得到多个Stream<Character>流集合
            //可以理解为Stream流中包含Stream<Character>流
            //因为这里的testCharacter()的方法我返回的是一个Stream<Character>
            //Stream<Stream<Character>> streamStream = stream.map((e) -> testCharacter(e));
            Stream<Stream<Character>> streamStream = stream.map((e) -> {
                List<Character> list = new ArrayList<>();
                for (Character c : e.toCharArray()) {
                    list.add(c);
                }
                return list.stream();
            });
            streamStream.forEach((e)->{
                e.forEach((e2)->{
                    System.out.println(e2);
                });
            });
            Stream<String> stm=Stream.of("aaa","bbbb","ccccc");
            //flatMap()方法即是把将得到的多个Stream<Character>流集合合并为一个一个Stream<Character>流集合
            Stream<Character> stream1=stm.flatMap(StreamTest04::testCharacter);
            //streamStream.forEach(System.out::println);
            System.out.println("---------------");
            stream1.forEach(System.out::println);
        }
        //返回一个Stream
        public static Stream<Character> testCharacter(String str){
            List<Character> list=new ArrayList<>();
            for (Character c:str.toCharArray()){
                list.add(c);
            }
            Stream<Character> stream=list.stream();
            return stream;
        }
    }
    
    

    终止操作

    查找与匹配

    • allMatch:检查是否匹配所有元素;
    • anyMatch:检查是否至少匹配一个元素;
    • noneMatch:检查是否没有匹配所有元素;
    • findFirst:返回第一个元素;
    • findAny:返回当前流中的任意元素;
    • count:返回流中元素的总个数;
    • max:返回流中最大值;
    • min:返回流中最小值;

    代码实例

    package com.ysh.review01_Stream;
    
    import java.util.Optional;
    import java.util.stream.Stream;
    
    /**
     * Stream中的终止操作
     */
    public class StreamTest06 {
        public static void main(String[] args) {
            //获取Stream
            Stream<String> stm1=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //allMatch()方法里面的参数是一个断言式接口,即实现必须重写test()方法
            boolean b1 = stm1.allMatch((t) -> {
                //检查是否匹配所有元素
                return t.length() > 2;
            });
            Stream<String> stm2=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            boolean b2=stm2.anyMatch((t) -> {
                //检查是否至少匹配一个元素
                return t.length() > 2;
            });
            Stream<String> stm3=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            boolean b3=stm3.noneMatch((t) -> {
                //检查是否没有匹配所有元素
                return t.length() > 2;
            });
            Stream<String> stm4=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //得到流中的第一个元素
            Optional<String> first = stm4.findFirst();
            //输出
            System.out.println(first.get());
            Stream<String> stm5=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //返回当前流中的任意元素
            Optional<String> any = stm5.findAny();
            System.out.println(any.get());
            Stream<String> stm6=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //放回流中元素的总个数
            long count = stm6.count();
            System.out.println(count);
            Stream<String> stm7=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //返回流中最大值,即长度最长,长度相同则比较ASCLL值大小
            Optional<String> max = stm7.max((s1, s2) -> {
                if (s1.length()==s2.length()){
                    return s1.compareTo(s2);
                }
                return s1.length() - s2.length();
            });
            System.out.println(max.get());
            Stream<String> stm8=Stream.of("aaaaaa","bbbbb","cccccc","dd","eee");
            //返回流中最小值,即长度最短,长度相同则比较ASCLL值大小
            Optional<String> min = stm8.min((s1, s2) -> {
                if (s1.length() == s2.length()) {
                    return s2.compareTo(s1);
                }
                return s1.length() - s2.length();
            });
            System.out.println(min.get());
            System.out.println(b3);
        }
    }
    
    

    收集:

    收集-将流转换为其他形式,接收一个Collertor接口的实现,用于给Stream中元素做 汇总的方法

    • List:把流中所有元素收集到List中,使用.collect(Collectors.toList());
    • Set:把流中所有元素收集到Set中,删除重复项,使用.collect(Collectors.toSet());
    • Map:把流中所有元素收集到Map中,当出现相同的key时会抛异常,使用 .collect(Collectors.toMap());
    • 使用collect方法求流中共有几条数据,使用.collect(Collectors.counting())
    • 使用collect方法求平均数,使用.collect(Collectors.averagingInt();
    • 使用collect方法求某个变量的总和,使用.collect(Collectors.summingDouble());
    • 使用collect方法且某个变量中值的最大值,使用.collect(Collectors.maxBy());

    代码实例

    package com.ysh.review01_Stream.one;
    
    import java.util.*;
    import java.util.stream.Collectors;
    
    public class StreamTest07 {
        public static void main(String[] args) {
            Student stu1=new Student("1","hhhh",18);
            Student stu2=new Student("2","hhhhh",19);
            Student stu3=new Student("3","oooooo",19);
            Student stu4=new Student("4","aaaaa",19);
            List<Student> list = Arrays.asList(stu1,stu2,stu3,stu4);
            //获取所有学生的姓名流,并且存储再List集合中
            List<String> collect = list.stream().map((e) -> {
                return e.getName();
            }).collect(Collectors.toList());
            System.out.println(collect);
            Set<String> set = list.stream().map((e) -> {
                return e.getName();
            }).collect(Collectors.toSet());
            System.out.println(collect);
            //将学生的姓名和年龄放入到一个集合中,当出现相同的key是会抛出一个java.lang.IllegalStateException: Duplicate key异常
            Map<String, Integer> map = list.stream().collect(Collectors.toMap((e) -> e.getName(), (e2) -> e2.getAge()));
            System.out.println(map);
            //运用collect输出所有学生的总数
            Long count2 = list.stream().collect(Collectors.counting());
            System.out.println(count2);
            //运用collect方法计算所有学生的平均年龄
            Double collect1 = list.stream().collect(Collectors.averagingDouble((n) -> n.getAge()));
            System.out.println(collect1);
            //运用collect方法求所有学生的年龄之和
            int agesum=list.stream().collect(Collectors.summingInt((e)->e.getAge()));
            System.out.println(agesum);
            //运用collect方法求所有学生中年龄最大的
            Optional<Student> max2 = list.stream().collect(Collectors.maxBy((a1, a2) -> a1.getAge() - a2.getAge()));
            System.out.println(max2.get());
    
        }
    }
    class Student {
        private String id;
        private String name;
        private int age;
        public Student(){
    
        }
    
        public Student(String id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return age == student.age &&
                    id.equals(student.id) &&
                    name.equals(student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id, name, age);
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    作者:前程有光
    链接:https://juejin.im/post/6888549645908181005
    来源:掘金

    相关文章

      网友评论

        本文标题:Stream流的这些操作,你得知道,对你工作有很大帮助

        本文链接:https://www.haomeiwen.com/subject/zescvktx.html