Stream流

1. 初始Stream流

  1. Stream流的作用: 结合了Lambda表达式, 简化集合和数组的操作

  2. Stream流的使用步骤:

    • (1) 先得到一条Stream流(流水线), 并把数据放上去
    • (2) 利用Stream流中的API进行各种操作
      各种操作主要包含两种: (1) 中间方法: 如过滤和转换(方法调用完毕之后, 还可以调用其他方法) (2) 终结方法: 如统计和打印(最后一步调用完毕之后, 不能调用其他方法)

2. Stream流的使用步骤

2.1 先得到一条Stream流(流水线), 并把数据放上去

  1. 对于无法直接使用Stream流的双列集合, 需要使用方法keySet或者entrySet先转换成单列集合
    image
// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "a", "b", "c", "d", "e");
        // 获取到一条流水线, 并且把集合中的数据映射到Stream流中
//        Stream<String> stream1 = list.stream();
        // 使用终结符方法, 打印集合中的数据
        // (1) lamda写法
//        stream1.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
        // (2) 化简写法
        list.stream().forEach(s -> System.out.println(s));

        // 2. 双列集合获取Stream流(需要用单列集合转换)
        HashMap<String, Integer> hm = new HashMap<>();
        hm.put("aa", 1);
        hm.put("bb", 2);
        hm.put("cc", 3);
        // (1) 第一种获取Stream流
        hm.keySet().stream().forEach(s -> System.out.println(s)); // "aa", "bb", "cc", "dd"
        // (1) 第二种获取Stream流
        hm.entrySet().stream().forEach(entry -> System.out.println(entry.getKey())); // "aa", "bb", "cc", "dd"

        // 3. 数组获取Stream流
        int[] arr = {1, 2, 3, 4, 5};
        Arrays.stream(arr).forEach(i -> System.out.println(i));

        // 4. 一堆零散数据获取Stream流(需要确保数据类型相同)
        Stream.of(1, 2, 3, 4, 5).forEach(i -> System.out.println(i));
  1. Stream接口中静态方法of的细节:
    • 方法的形参是一个可变参数, 可以传递一堆零散的数据, 也可以传递数组
    • 数组必须是引用数据类型的, 若为基本数据类型, 会把数组整体当一个元素, 放在Stream, 打印出地址值

2.2 Stream流的中间方法

  1. 中间方法, 返回新的Stream流, 原来的Stream流只能使用一次, 建议使用链式编程
  2. 修改Stream流中的数据, 不会影响原来集合或者数组中的数据
    image

1. filter过滤

// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三", "张无忌", "里斯", "王五");

        // filter过滤 把张开头的留下,其余数据过滤不要
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                // 如果返回值为true,则数据保留
                return s.startsWith("张");
            }
        }).forEach(s -> System.out.println(s));

        list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));

2. limit获取前几个元素

// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三", "张无忌", "里斯", "王五");

        // 获取前三个元素
        list.stream().limit(3)
                .forEach(s-> System.out.println(s));

3. skip获取前几个元素

// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三", "张无忌", "里斯", "王五");

        // 跳过前三个元素
        list.stream().skip(3)
                .forEach(s-> System.out.println(s));

4. distinct去重

  1. 记得手写equals和hashCode方法
// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三", "张无忌", "里斯", "王五", "王五");
        list.stream().distinct().forEach(s-> System.out.println(s));

5. concat合并

        // 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三", "张无忌", "里斯", "王五", "王五");
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2, "liu");
        Stream.concat(list.stream(), list2.stream())
                .forEach(s-> System.out.println(s));

6. map转换流中的数据类型

// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
        // 只获取里面的年龄并打印: String->int
        // 第一个类型: 流中原本的数据类型
        // 第二个类型: 流中想要获取的数据类型
        // 当map方法执行完之后, s依次表示流中的每一个数据, 为整数
        list.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String[] arr = s.split("-");
                String ageStr = arr[1];
                int age = Integer.parseInt(ageStr);
                return age;
            }
        }).forEach(s->System.out.println(s));

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

2.3 Stream流的终结方法

image

1. forEach()

// 1. 单列集合获取Stream流
        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");
        // 只获取里面的年龄并打印: String->int
        // 第一个类型: 流中原本的数据类型
        // 第二个类型: 流中想要获取的数据类型
        // 当map方法执行完之后, s依次表示流中的每一个数据, 为整数
        list.stream().map(s->Integer.parseInt(s.split("-")[1]))
                .forEach(s->System.out.println(s));

2. count()统计

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");

        System.out.println(list.stream().count());

3. toArray()收集流中的数据并放到数组中

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-18", "张无忌-19", "里斯-20", "王五-21", "王五-26");

        // 1. 无参
        Object[] array = list.stream().toArray();
        System.out.println(Arrays.toString(array));

        // 2. 带参如下图
        // IntFunction的范型: 具体类型的数组
        // apply的形参: 流中数据的个数, 要跟数组的长度保持一致
        // apply的返回值: 具体类型的数组
        // 方法体: 就是创建数组
//        list.stream().toArray(new IntFunction<? extends Object[]>() {
//            @Override
//            public Object[] apply(int value) {
//                return new Object[0];
//            }
//        })
        String[] array1 = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(array1));

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

4. collector

1. 收集到List集合当中

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");

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

2. 收集到Set集合当中

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");

        // 收集到List集合当中
        // 需求: 把所有的男性收集起来
        Set<String> set1 = list.stream().filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());
        System.out.println(set1);

3. 收集到Map集合当中

如果我们要收集到Map集合当中, 键不能重复, 否则会报错

        ArrayList<String> list = new ArrayList<>();
        Collections.addAll(list, "张三-男-18", "张无忌-男-19", "里斯-男-20", "王五-女-21");

        // 收集到Map集合当中
        // 需求: 把所有的男性收集起来
        // 键: 姓名, 值: 年龄
        // toMap先写键的规则, 再写值的规则
        Map<String, Integer> map1 = list.stream()
                .filter(s -> s.split("-")[1].equals("男"))
                /*
                 toMap: 参数一表示键的生成规则, 参数二表示值的生成规则
                 参数一:
                    Function范型一: 表示流中每一个数据类型
                            范型二: 表示Map集合中的键的类型

                    方法apply形参: 依次表示流中的每一个数据
                    方法apply返回值: 键
                 参数二:
                    Function范型一: 表示流中每一个数据类型
                            范型二: 表示Map集合中的值的类型

                    方法apply形参: 依次表示流中的每一个数据
                    方法apply返回值: 值
                 */
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {
                        return s.split("-")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split("-")[2]);
                    }
                }));
        System.out.println(map1);

        Map<String, Integer> map2 = list.stream().filter(s -> s.split("-")[1].equals("男"))
                .collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
        System.out.println(map2);
posted @ 2025-08-16 15:43  awei040519  阅读(27)  评论(0)    收藏  举报