Stream流

1.体验Stream流

  • 案例需求

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

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

    • 把集合中所有以"张"开头的元素存储到一个新的集合

    • 把"张"开头的集合中的长度为3的元素存储到一个新的集合

    • 遍历上一步得到的集合

  • 原始方式示例代码

cpp 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class demo1 {
    public static void main(String[] args) {
 /*
案例需求
按照下面的要求完成集合的创建和遍历
- 创建一个集合,存储多个字符串元素
- 把集合中所有以"张"开头的元素存储到一个新的集合
- 把"张"开头的集合中的长度为3的元素存储到一个新的集合
- 遍历上一步得到的集合
*/
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤");
        ArrayList<String> list2 = new ArrayList<>();
        //- 把集合中所有以"张"开头的元素存储到一个新的集合
        //遍历list1把以张开头的元素添加到list2中。
        for (String name : list1) {
            if (name.startsWith("张")) {
                list2.add(name);
            }
        }
        System.out.println(list2);
        //- 把"张"开头的集合中的长度为3的元素存储到一个新的集合
        ArrayList<String> list3 = new ArrayList<>();
        for (String name : list2) {
            if(name.length()==3){
                list3.add(name);
            }
        }
        System.out.println(list3);

    }
}

使用Stream流示例代码

cpp 复制代码
public class demo2 {
    public static void main(String[] args) {
        //使用Stream流示例代码
        //集合的批量添加
        ArrayList<String> list1 = new ArrayList<>(List.of("张三丰","张无忌","张翠山","王二麻子","张良","谢广坤"));
        list1.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name-> System.out.println(name));
    }
}

2.Stream流的常见生成方式

Stream流的思想

  • Stream流的三类方法

    • 获取Stream流

      • 创建一条流水线,并把数据放到流水线上准备进行操作
    • 中间方法

      • 流水线上的操作

      • 一次操作完毕之后,还可以继续进行其他操作

    • 终结方法

      • 一个Stream流只能有一个终结方法

      • 是流水线上的最后一个操作

  • 生成Stream流的方式

    • Collection体系集合

      使用默认方法stream()生成流, default Stream<E> stream()

    • Map体系集合

      把Map转成Set集合,间接的生成流

    • 数组

      通过Arrays中的静态方法stream生成流

    • 同种数据类型的多个数据

      通过Stream接口的静态方法of(T... values)生成流

sql 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.stream.Stream;

public class demo3 {
    public static void main(String[] args) {
        /*
        单列集合      default Stream<E> stream()                           Collection中的默认方法
        双列集合      无                                                   无法直接使用stream流
        数组          public static <T> Stream<T> stream(T[] array)        Arrays工具类中的静态方法
        一堆零散数据   public static<T> Stream<T> of(T... values)           Stream接口中的静态方法
*/
        //使用单列集合创建stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc");
        list.stream().forEach(s->System.out.println(s));
        System.out.println("----------------------");
        //使用双列集合创建stream流
        HashMap<String,Integer> hm = new HashMap<>();
        hm.put("aaa",1);
        hm.put("bbb",2);
        hm.put("ccc",3);
        //第一种获取stream流
        //先获取一个键值对对象,把键值对对象放到了stream流,这里的s相当于每一个键值对对象
        hm.entrySet().stream().forEach(s-> System.out.println(s));
        //第二种获取stream流
        //先获取所有的键,把键放在stream流,这里的s相当于每一个键
        hm.keySet().stream().forEach(s-> System.out.println(s));
        System.out.println("----------------------");
        //使用数组创建stream流
        int []arr1 = {1,2,3,4,5};
        Arrays.stream(arr1).forEach(s-> System.out.print(s+" "));
        System.out.println();
        String[] arr2 = {"aaa","bbb","ccc"};
        Arrays.stream(arr2).forEach(s-> System.out.print(s+" "));
        System.out.println();

        //注意:
        //Stream接口中静态方法of的细节
        //方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
        //但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当做一个元素,放到Stream当中。
        Stream.of(arr1).forEach(s-> System.out.println(s+" "));//[I@30dae81
        Stream.of(arr2).forEach(s-> System.out.println(s+" "));

        System.out.println("----------------------");
        //使用一堆零散数据创建stream流
        Stream.of(1,2,3,4,5).forEach(s-> System.out.print(s+" "));
        Stream.of("a","b","c","d","e").forEach(s-> System.out.print(s+" "));
    }
}

3.Stream流中间操作方法

  • 概念

    中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作

ruby 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.SortedMap;

/*
          filter              过滤
          limit               获取前几个元素
          skip                跳过前几个元素

          注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
          注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
      */
public class demo4 {
    public static void main(String[] args) {
        //1.  filter 过滤
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
        //filter   过滤  把张开头的留下,其余数据过滤不要
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));

        //注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
        //list的集合还是不会变化
        System.out.println(list);
        System.out.println("====================================");
        //2 . limit  获取前几个元素
        list.stream().limit(3).forEach(s -> System.out.println(s));//张无忌", "周芷若", "赵敏
        System.out.println("====================================");
        //3. skip  跳过前几个元素
        list.stream().skip(3).limit(3).forEach(s -> System.out.println(s));//张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤



    }
}
ruby 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Stream;

/*
         distinct            元素去重,依赖(hashCode和equals方法)
         concat              合并a和b两个流为一个流

         注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
         注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
     */
public class demo5 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
        Collections.addAll(list1, "张无忌","张无忌","张无忌", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
       //1. distinct     元素去重,依赖(hashCode和equals方法)
        list1.stream().distinct().forEach(s->System.out.println(s));
        System.out.println("-------------------------------------");
        //2.    concat              合并a和b两个流为一个流
        //创建一个新的集合
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2,"周芷若", "赵敏");
        Stream.concat(list1.stream(), list2.stream()).distinct().forEach(s->System.out.println(s));


    }
}
ruby 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;

public class demp6 {
    public static void main(String[] args) {
            /*
            map                 转换流中的数据类型

            注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
            注意2:修改Stream流中的数据,不会影响原来集合或者数组中的数据
        */
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-15", "周芷若-14", "赵敏-13", "张强-20", "张三丰-100", "张翠山-40", "张良-35", "王二麻子-37", "谢广坤-41");
        //需求:只获取里面的年龄并进行打印
        //String->int

        //第一个类型:流中原本的数据类型
        //第二个类型:要转成之后的类型

        //apply的形参s:依次表示流里面的每一个数据
        //返回值:表示转换之后的数据

        //当map方法执行完毕之后,流上的数据就变成了整数
        //所以在下面forEach当中,s依次表示流里面的每一个数据,这个数据现在就是整数了
       /* list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");//张无忌-15
                String ageString = arr[1];//15
                int age = Integer.parseInt(ageString);
                return age;

            }
        }).forEach(s-> System.out.println(s));*/

        list.stream().map(s->Integer.parseInt(s.split("-")[1])).forEach(s-> System.out.println(s));
    }
}

4.Stream流终结操作方法

  • 概念

    终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

  • 常见方法

ruby 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;

public class demo7 {
    public static void main(String[] args) {
        /*
            void forEach(Consumer action)           遍历
            long count()                            统计
            toArray()                               收集流中的数据,放到数组中
       */


        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰", "张翠山", "张良", "王二麻子", "谢广坤");
        //void forEach(Consumer action)           遍历

        //Consumer的泛型:表示流中数据的类型
        //accept方法的形参s:依次表示流里面的每一个数据
        //方法体:对每一个数据的处理操作(打印)
        list.stream().forEach(s -> System.out.println(s));
        System.out.println("------------------------");
        //2.   long count()                            统计
        System.out.println(list.stream().count());
        System.out.println("-----------------------");
        //3. toArray()                               收集流中的数据,放到数组中
        //Object[] arr1 = list.stream().toArray();
        //System.out.println(Arrays.toString(arr1));

        //IntFunction的泛型:具体类型的数组
        //apply的形参:流中数据的个数,要跟数组的长度保持一致
        //apply的返回值:具体类型的数组
        //方法体:就是创建数组


        //toArray方法的参数的作用:负责创建一个指定类型的数组
        //toArray方法的底层,会依次得到流里面的每一个数据,并把数据放到数组当中
        //toArray方法的返回值:是一个装着流里面所有数据的数组
      /*  String[] arr = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr));*/

        System.out.println(Arrays.toString( list.stream().toArray(value -> new String[value])));

    }
}
ruby 复制代码
package Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class demo8 {
    public static void main(String[] args) {
       /* collect(Collector collector)            收集流中的数据,放到集合中 (List Set Map)

        注意点:
        如果我们要收集到Map集合当中,键不能重复,否则会报错
                */

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张无忌-男-15", "周芷若-女-14", "赵敏-女-13", "张强-男-20",
                "张三丰-男-100", "张翠山-男-40", "张良-男-35", "王二麻子-男-37", "谢广坤-男-41");

        //收集List集合当中
        //需求:
        //我要把所有的男性收集起来
        list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toList())
                .forEach(s -> System.out.println(s));
        System.out.println("----------------------");

        //收集Set集合当中
        //需求:
        //我要把所有的男性收集起来
        //set集合与list区别就在于set能去重
        list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet())
                .forEach(s -> System.out.println(s));
        System.out.println("--------------------------------");


        //收集Map集合当中
        //谁作为键,谁作为值.
        //我要把所有的男性收集起来
        //键:姓名。 值:年龄


        /*
        toMap:参数一:表示键的生成规则
              参数二:表示值的生成规则

         参数一:
                Function泛型一:表示流中的每一个数据的类型
                        泛型二:表示Map集合中键的数据类型

                方法apply形参:依次表示流里的每一个数据
                         方法体: 生成键的代码
                         返回值:已经生成的键


         参数二:
                Function泛型一:表示流中的每一个数据的类型
                        泛型二:表示Map集合中值的数据类型

                方法apply形参:依次表示流里的每一个数据
                         方法体: 生成值的代码
                         返回值:已经生成的值

         */
        Map<String, Integer> newmap = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        //张无忌-男-15
                        return s.split("-")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split("-")[2]);
                    }
                }));
        System.out.println(newmap);
        System.out.println("---------------------");

        Map<String, Integer> map = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
        System.out.println(map);
    }
}

5.练习

cpp 复制代码
public class demo1 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9,10);
        list.stream()
                .filter(x -> x % 2 == 0)
                .collect(Collectors.toList())
                .forEach(s->System.out.println(s));
    }
}
cs 复制代码
package lx;

import java.util.ArrayList;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class demo2 {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();
        Student s1 = new Student("zhangsan", 23);
        Student s2 = new Student("lisi", 24);
        Student s3 = new Student("wangwu", 25);
        list.add(s1);
        list.add(s2);
        list.add(s3);
        Map<String, Integer> newmap =
                list.stream()
                .filter(student -> student.getAge() >=24)
                .collect(Collectors.toMap(new Function<Student, String>() {
                    @Override
                    public String apply(Student student) {
                        return student.getName();
                    }
                }, new Function<Student, Integer>() {
                    @Override
                    public Integer apply(Student student) {
                        return student.getAge();
                    }
                }));
        System.out.println(newmap);
        System.out.println("-----------------");
        //lambda表达式
        Map<String, Integer> newmap2 = list.stream()
                .filter(student -> student.getAge() > 24)
                .collect(Collectors.toMap(student -> student.getName(), student -> student.getAge()));
        System.out.println(newmap2);

    }
cs 复制代码
package lx;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class demo3 {
    public static void main(String[] args) {
       /*
        现在有两个ArrayList集合,分别存储6名男演员的名字和年龄以及6名女演员的名字和年龄。
        姓名和年龄中间用逗号隔开。
        比如:张三,23
        要求完成如下的操作:
        1,男演员只要名字为3个字的前两人
        2,女演员只要姓杨的,并且不要第一个
        3,把过滤后的男演员姓名和女演员姓名合并到一起
        4,将上一步的演员信息封装成Actor对象。
        5,将所有的演员对象都保存到List集合中。
        备注:演员类Actor,属性有:name,age

        男演员:  "蔡坤坤,24" , "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27"
        女演员:  "赵小颖,35" , "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33"
      */


        //1.创建两个ArrayList集合
        ArrayList<String> manList = new ArrayList<>();
        ArrayList<String> womenList = new ArrayList<>();
        //2.添加数据
        Collections.addAll(manList, "蔡坤坤,24", "叶齁咸,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");
        Collections.addAll(womenList, "赵小颖,35", "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");
        //3.男演员只要名字为3个字的前两人
        Stream<String> stream1 = manList.stream()
                .filter(s -> s.split(",")[0].length() == 3)
                .limit(2);

        //4.女演员只要姓杨的,并且不要第一个
        Stream<String> stream2 = womenList.stream()
                .filter(s -> s.split(",")[0].startsWith("杨"))
                .skip(1);

        //5,把过滤后的男演员姓名和女演员姓名合并到一起
        //Stream.concat(stream1,stream2);


        //6.将上一步的演员信息封装成Actor对象。
        //String -> Actor对象 (类型转换)

        //第一个类型:流中原本的数据类型
        //第二个类型:要转成之后的类型

        //apply的形参s:依次表示流里面的每一个数据
        //返回值:表示转换之后的数据

        //当map方法执行完毕之后,流上的数据就变成了Actor
        //所以在下面forEach当中,s依次表示流里面的每一个数据,这个数据现在就是Actor类型的数据了
       /* Stream.concat(stream1, stream2).map(new Function<String, Actor>() {
            @Override
            public Actor apply(String s) {
                //赵小颖,35
                String[] arr = s.split(",");
                String name = arr[0];//赵小颖
                int age = Integer.parseInt(arr[1]);
                return new Actor(name, age);
            }
        });*/
        //7,将所有的演员对象都保存到List集合中。

        List<Actor> newlist = Stream.concat(stream1, stream2)
                .map(s -> new Actor(s.split(",")[0],
                        Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());
        System.out.println(newlist);

    }
}

​​​​​​​

相关推荐
程序媛小果8 分钟前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
小屁孩大帅-杨一凡34 分钟前
java后端请求想接收多个对象入参的数据
java·开发语言
m0_6569747439 分钟前
C#中的集合类及其使用
开发语言·c#
java1234_小锋41 分钟前
使用 RabbitMQ 有什么好处?
java·开发语言
九鼎科技-Leo1 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
wjs20241 小时前
R 数据框
开发语言
TangKenny1 小时前
计算网络信号
java·算法·华为
肘击鸣的百k路1 小时前
Java 代理模式详解
java·开发语言·代理模式
城南vision1 小时前
Docker学习—Docker核心概念总结
java·学习·docker
捕鲸叉1 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式