• Stream流


    在这里插入图片描述

    一. 体验Stream流

    • 需求:按照下面的要求完成集合的创建和遍历
    1. 创建一个集合,存储多个字符串元素
    2. 把集合中所有以"菜"开头的元素存储到一个新的集合
    3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
    4. 遍历上一步得到的集合
    • 代码演示
    package Demo;
    
    import java.util.ArrayList;
    
    public class StreamDemo {
        /*
           需求:按照下面的要求完成集合的创建和遍历
           1. 创建一个集合,存储多个字符串元素
           2. 把集合中所有以"菜"开头的元素存储到一个新的集合
           3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
           4. 遍历上一步得到的集合
         */
        public static void main(String[] args) {
    //               1. 创建一个集合,存储多个字符串元素
            ArrayList<String> s = new ArrayList<String>();
            s.add("菜xk");
            s.add("菜徐琨");
            s.add("菜鸡");
            s.add("鸡你太美");
            s.add("打篮球");
    
    //               2. 把集合中所有以"菜"开头的元素存储到一个新的集合
            ArrayList<String> s1 = new ArrayList<String>();
            for (String ss1 : s) {
                if (ss1.startsWith("菜")){
                    s1.add(ss1);
                }
            }
    //        System.out.print(s1);
    //               3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
            ArrayList<String> s2 = new ArrayList<String>();
            for (String ss2 : s1){
                if (ss2.length()==3){
                    s2.add(ss2);
                }
            }
    //               4. 遍历上一步得到的集合
            for (String ss3 : s2){
                System.out.println(ss3);
            }
            System.out.println("-------------------------------------------------");
    
            //Stream流来改进
            //s.stream().filter(ss ->ss.startsWith("菜")).filter(ss-> ss.length()==3).forEach(ss -> System.out.println(ss));
    //        ss -> System.out.println(ss)可以改进为System.out::println
            s.stream().filter(ss -> ss.startsWith("菜")).filter(ss-> ss.length()==3).forEach(System.out::println);
    //        直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:生成流、过滤姓菜、过滤长度为3、逐一打印
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    输出内容为:
    菜xk
    菜徐琨


    菜xk
    菜徐琨

    重点代码:
    s.stream().filter(ss -> ss.startsWith(“菜”)).filter(ss-> ss.length()==3).forEach(System.out::println);

    在这里插入图片描述

    二. Stream流的生成方式

    • Collection体系的集合可以使用 默认方法stream() 生成流
      default Stream stream()

    • Map体系的集合间接的生成流

    • 数组可以通过Stream接口的 静态方法of(T…values) 生成流

    • Stream流的使用

    1. 生成流
      通过 数据源的集合,数组等生成流
      list.Stream()
    2. 中间操作
      一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用
      filter()
    3. 终结操作
      一个流只能有一个终结操作,当这个操作执行后,流就被用"光"了,无法再被操作,所以这必定是流的最后一个操作forEach()
    package Demo;
    
    import java.lang.reflect.Array;
    import java.util.*;
    import java.util.stream.Stream;
    
    public class StreamDemo2 {
       
        public static void main(String[] args) {
        
    //        Collection体系的集合可以使用默认方法stream()生成流   default Stream stream()
            List<String> list = new ArrayList<>();
            Stream<String> stream = list.stream();//list集合下生成的流
            
    
            Set<String> set = new HashSet<>();
            Stream<String> stream1 = set.stream();//set集合下生成的流
    
    
    //        Map体系的集合间接的生成流
            Map<String, Integer> map = new HashMap<>();
            
    
            //键的流
            Set<String> strings = map.keySet();
            Stream<String> stream2 = strings.stream();
            
    
            //值得流
            Collection<Integer> values = map.values();
            Stream<Integer> stream3 = values.stream();
            
    
            //键值对的流
            Stream<Map.Entry<String, Integer>> stream4 = map.entrySet().stream();
            
    
    
    //        数组可以通过Stream接口的静态方法of(T...values)生成流   注意:可变参数就是数组哦
            int[] array = {8, 5, 6};
            Stream<int[]> array1 = Stream.of(array);//数组流
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    三. 常见的Stream流的中间操作和终结操作

    方法名方法说明
    Stream< T > filter(Predicate predicate);(Predicate接口中的方法 boolean test(T t)):对给定的参数进行判断,返回一个布尔值用于对流中的数据进行过滤
    Stream< T > limit(long maxSize);返回此流中的元素组成的流,截取前指定参数个数的数据
    Stream< T > skip(long n);返回此流中的元素组成的流,截取前指定参数个数的数据,返回由该流的剩余元素组成的流
    static Stream< T > concat(Stream a,Stream b);合并a和b两个流为一个流
    static Stream< T > distinct();返回由流中不同的元素(根据Object equals(Object))组成的流
    Stream< T >sorted();返回由此流的元素组成的流,根据自然顺序排序
    Stream< T > sorted(Comparator comparator);(Comparator接口中的方法 int compare(T o1,T o2) )返回由此流的元素组成的流,根据Comparator进行排序
    < R > Stream< R > map(Function mapper);Function接口中的方法 R apply(T t)//返回想要的类型返回由给定函数应用于此流的元素的结果组成的流
    IntStream mapToInt(ToIntFunction mapper);(IntStream:表示原始的int流)ToIntFunction:接口中的方法 int applyAsInt(T value)//返回指定的类型int int sum()返回此流中元素的和返回一个IntStream其中包含将给定函数应用于此流的元素的结果
    void forEach(Consumer action);对此流的每个元素执行操作
    long count();返回此流中的元素数

    1. Stream< T > limit(long maxSize)和Stream< T > skip(long n)的使用

    需求:按照下面的要求完成集合的创建和遍历

    1. 创建一个集合,存储多个字符串元素
    2. 把集合中所有以"菜"开头的元素存储到一个新的集合
    3. 把"菜"字开头的集合的长度为3的元素存储到一个新的集合
    4. 遍历上一步得到的集合
    package Demo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class StreamDemo3 {
        public static void main(String[] args) {
            //创建一个集合,存储多个字符串元素
            List<String> as = new ArrayList<>();
            as.add("菜坤");
            as.add("iKun");
            as.add("鸡你太美");
            as.add("菜菜");
            as.add("打篮球");
            as.add("时长两年半");
            as.add("rap");
    
            //需求1:取前3个数据在控制台输出
            as.stream().limit(3).forEach(System.out::println);
            System.out.println("------");
    
            //需求2:跳过3个元素,把剩下的元素在控制台输出
            as.stream().skip(3).forEach(s-> System.out.println(s));
            System.out.println("------");
    
            //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
            as.stream().skip(2).limit(2).forEach(System.out::println);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    输出的内容:
    菜坤
    iKun
    鸡你太美


    菜菜
    打篮球
    时长两年半
    rap


    鸡你太美
    菜菜

    2. static Stream< T > concat(Stream a,Stream b)和static Stream< T > distinct();的使用

    创建一个集合,存储多个字符串元素

    1. 需求1:跳过2个数据组成一个流
    2. 需求2:合并需求1和需求2得到的流.并把结果在控制台输出
    3. 需求3:合并需求1和需求2得到的流,并且元素不能相同,并把结果在控制台输出
      注意:当时用一个流完成终结操作后,那么这个流也就结束了,再次生成需要重新调用
    package Demo;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Stream;
    
    public class StreamDemo4 {
        public static void main(String[] args) {
            //创建一个集合,存储多个字符串元素
            List<String> as = new ArrayList<>();
            as.add("菜徐琨");
            as.add("时长两年半");
            as.add("唱跳rap");
            as.add("打篮球");
            as.add("鸡你太美");
    
            //创建一个集合,存储多个字符串元素
            Stream<String> s1 = as.stream().limit(4);
    
            //需求2:跳过2个数据组成一个流
            Stream<String> s2 = as.stream().skip(2);
    
            //需求3:合并需求1和需求2得到的流.并把结果在控制台输出
    //        Stream.concat(s1,s2).forEach(s-> System.out.println(s))+;
    
            //注意:当时用一个流完成终结操作后,那么这个流也就结束了,再次生成需要重新调用
    
            //需求3:合并需求1和需求2得到的流,并且元素不能相同,并把结果在控制台输出
            Stream.concat(s1,s2).distinct().forEach(System.out::println);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    输出的内容:
    菜徐琨
    时长两年半
    唱跳rap
    打篮球
    鸡你太美

    3. Stream< T >sorted()和Stream< T >sorted(Comparator comparator);

    创建一个集合,存储多个字符串元素

    1. 需求1:存储多个字符串元素,按照字母顺序把数据在控制台输出
    2. 需求2:按照字母长度把数据在控制台输出
    package Demo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class StreamDemo5 {
        public static void main(String[] args) {
         
            //创建一个集合,存储多个字符串元素
            List<String> as = new ArrayList<>();
            as.add("cxk1");
            as.add("bxaxk");
            as.add("dxxk4");
            as.add("axk3");
            as.add("cxk2");
    
            //需求1:存储多个字符串元素,按照字母顺序把数据在控制台输出
            as.stream().sorted().forEach(s-> System.out.println(s));
            System.out.println("---------------------------");
    
            //需求2:按照字母长度把数据在控制台输出
            as.stream().sorted((s1,s2)->
                    {
                        int num = s1.length()-s2.length();
                        int num2 = num==0?s1.compareTo(s2):num;
                        return num2;
                    }
                    ).forEach(System.out::println);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    输出的内容为:
    axk3
    bxaxk
    cxk1
    cxk2
    dxxk4


    axk3
    cxk1
    cxk2
    bxaxk
    dxxk4

    4. < R > Stream< R > map(Function mapper):和IntStream mapToInt(ToIntFunction mapper);的使用

    • < R > Stream< R > map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
      Function接口中的方法 R apply(T t)//返回想要的类型
    • IntStream mapToInt(ToIntFunction mapper);返回一个IntStream其中包含将给定函数应用于此流的元素的结果
      IntStream:表示原始的int流
      ToIntFunction:接口中的方法 int applyAsInt(T value)//返回指定的类型int int sum()返回此流中元素的和
    package Demo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /*
         Stream map(Function mapper):返回由给定函数应用于此流的元素的结果组成的流
           Function接口中的方法    R apply(T t)//返回想要的类型
    
        IntStream mapToInt(ToIntFunction mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果
        IntStream:表示原始的int流
        ToIntFunction:接口中的方法    int applyAsInt(T value)//返回指定的类型int       int sum()返回此流中元素的和
     */
    public class StreamDemo6 {
        public static void main(String[] args) {
            //创建一个集合,存储多个字符创元素
            List<String> ls = new ArrayList<>();
    
            ls.add("2000");
            ls.add("3");
            ls.add("1");
            ls.add("18");
    
            //需求:将集合中的字符串数据转换为整数之后在控制台输出
    //        ls.stream().map(i->Integer.valueOf(i)).forEach(i-> System.out.println(i));
            ls.stream().map(Integer::valueOf).forEach(System.out::println);//方法的引用
    
            System.out.println("------------------------------");
    
            //需求:将集合中的字符串数据转换为特制的数据类型之后在控制台输出总和
            int sum = ls.stream().mapToInt(s -> Integer.parseInt(s)).sum();
            System.out.println(sum);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    5. Stream流的常见终结操作方法

    • void forEach(Consumer action): 对此流的每个元素执行操作
      consumer接口中的方法 void accept(T t): 给定的参数执行次操作

    • long count():返回此流中的元素数

    package Demo;
    
    import java.util.ArrayList;
    
    public class StreamDemo7 {
        public static void main(String[] args) {
            /*
            Stream流的常见终结操作方法
               void forEach(Consumer action): 对此流的每个元素执行操作
                   consumer接口中的方法        void accept(T t): 给定的参数执行次操作
    
               long count():返回此流中的元素数
             */
    
            //创建一个集合,存储多个字符串元素
            ArrayList<String> ss = new ArrayList<>();
            ss.add("菜徐琨");
            ss.add("菜头");
            ss.add("小黑子");
            ss.add("鸡你太美");
            ss.add("时长两年半");
            ss.add("爱打篮球");
    
    
            //需求1:把集合的元素在控制台输出
    //        ss.stream().forEach(s-> System.out.println(s));
            ss.stream().forEach(System.out::println);
    
            System.out.println("-------------------");
    
            //需求2:统计集合中有几个以"菜"开头的元素,并把统计结果在控制台输出
            long cou = ss.stream().filter(sss -> sss.startsWith("菜")).count();
            System.out.println("以\"菜\"开头的元素元素个数有"+cou+"个");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    四. Stream流的收集方法

    对数据使用Stream流的方式操作完毕后,我想把流中的数据收集到集合中,该怎么办呢?
    Stream流的收集方法

    方法名方法说明
    R collect(Collector collector);但是这个收集方法的参数是一个Collector接口

    工具类Collectors提供了具体的收集方式

    方法名方法说明
    public static < T > Collector toList();把元素收集到List集合中
    public static < T > Collector toSet();把元素收集到Set集合中
    public Collection toMap(Function keyMapper,Function valueMapper);把元素收集到Map集合中
    package Demo;
    
    import java.util.*;
    import java.util.stream.Collector;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    public class StreamDemo9 {
        public static void main(String[] args) {
            //创建List集合对象
            List<String> list = new ArrayList<String>();
            list.add("林青霞");
            list.add("张曼玉");
            list.add("王祖贤");
            list.add("柳岩");
    
            //需求1:得到名字为3个字的流
            Stream<String> stringStream = list.stream().filter(s -> s.length() == 3);
    
    
            //需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历
            List<String> stringList = stringStream.collect(Collectors.toList());
            for (String x:stringList){
                System.out.println(x);
            }
    
    
            //创建Set集合对象
            HashSet<Integer> set = new HashSet<>();
            set.add(10);
            set.add(20);
            set.add(30);
            set.add(33);
            set.add(35);
    
    
            //需求3:得到年龄大于25的流
            Stream<Integer> integerStream = set.stream().filter(age -> age > 25);
    
    
            //需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历
            Set<Integer> integerSet = integerStream.collect(Collectors.toSet());
            for (Integer x : integerSet){
                System.out.println(x);
            }
    
    
            //定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
            String[] strArray={"林青霞,30","张曼玉,35","王祖贤,33","柳岩,25"};
    
            //需求5:得到字符串中年龄数据大于28的流
            Stream<String> stringStream1 = Stream.of(strArray).filter(s -> Integer.valueOf(s.split(",")[1]) > 28);
    
            //需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
            Map<String, String> map1 = stringStream1.collect(Collectors.toMap(key -> key.split(",")[0], (value -> value.split(",")[1])));
            Set<String> strings = map1.keySet();
            for (String key : strings) {
                String s = map1.get(key);
                System.out.println(key+" "+s);
            }
         }
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    输出的内容:
    林青霞
    张曼玉
    王祖贤
    33
    35
    30
    林青霞 30
    王祖贤 33
    张曼玉 35

    五. 总和案例

    • 现在有两个Arraylist集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
      1. 男演员只要名字为3个字的前三人
      2. 女演员只要姓坤的,并且不要第一个
      3. 把过滤后的男演员姓名和女演员姓名个并在一起
      4. 把上一步的操作后的元素作为构造方法的参数创建演员对象,遍历数据
      5. 演员类Actor已经提供,里面有一个成员变量,一个构造方法,以及成员变量对应的get/set方法
    package Demo;
    
    import java.util.ArrayList;
    import java.util.stream.Stream;
    
    
    //演员类Actor已经提供,里面有一个成员变量,一个构造方法,以及成员变量对应的get/set方法
    class Actor{
        private  String name;
    
        public Actor() {
        }
    
        public Actor(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    public class StreamDemo8 {
        /*
          现在有两个Arraylist集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作
             男演员只要名字为3个字的前三人
             女演员只要姓坤的,并且不要第一个
             把过滤后的男演员姓名和女演员姓名个并在一起
             把上一步的操作后的元素作为构造方法的参数创建演员对象,遍历数据
                演员类Actor已经提供,里面有一个成员变量,一个构造方法,以及成员变量对应的get/set方法
         */
        public static void main(String[] args) {
            //男
            ArrayList<String> boys = new ArrayList<>();
            boys.add("菜徐琨");
            boys.add("喜羊羊");
            boys.add("美羊羊");
            boys.add("懒洋洋");
            boys.add("沸羊羊");
            boys.add("鸡你太美");
    
            //女
            ArrayList<String> girs = new ArrayList<>();
            girs.add("坤坤1");
            girs.add("坤坤2");
            girs.add("坤坤3");
            girs.add("坤坤4");
            girs.add("坤坤5");
            girs.add("坤坤6");
            girs.add("坤坤7");
    
            //男演员只要名字为3个字的前三人
            Stream<String> boy1 = boys.stream().limit(3);
    
            //女演员只要姓坤的,并且不要第一个
            Stream<String> gir2 = girs.stream().skip(1);
    
            //把过滤后的男演员姓名和女演员姓名个并在一起
            Stream<String> co = Stream.concat(boy1, gir2);
    
            //把上一步的操作后的元素作为构造方法的参数创建演员对象,遍历数据
            co.map((Actor::new)).forEach(s-> System.out.println(s.getName()));
            //(Actor::new)  相当于   Actor s -> return new Actor(s)
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    输入的内容:
    菜徐琨
    喜羊羊
    美羊羊
    坤坤2
    坤坤3
    坤坤4
    坤坤5
    坤坤6
    坤坤7

  • 相关阅读:
    [其他] ubuntu 22 上编译 ffmpeg
    【vue.js】vue中的Ajax——json-server
    将JavaBean交给IoC容器管理和依赖注入DI
    系统架构设计师(第二版)学习笔记----需求工程
    SpringBoot:使用Caffeine实现缓存
    lab1-2 初次遇见加壳程序
    猿创征文|宝藏工具篇|数字芯片设计,嵌入式开发,人工智能|没我可以,没你不行!
    计算机毕业设计Java智慧社区信息管理系统开发(源码+系统+mysql数据库+lw文档)
    obsidian和zotero联动
    Openssl X509 v3 AuthorityKeyIdentifier实验与逻辑分析
  • 原文地址:https://blog.csdn.net/o676448/article/details/125884760