# stream流

# 初识stream流

创建集合元素,完成以下需求,

  1. 把所有“张”开头的元素存储到新集合中
  2. 把“张”开头的元素,长度为3的元素存储到新集合中
  3. 遍历打印最终结果
package stream;

import java.util.ArrayList;

public class Main {


    public static void main(String[] args) {
//        创建集合元素,完成以下需求,
//
//        1. 把所有“张”开头的元素存储到新集合中
//        2. 把“张”开头的元素,长度为3的元素存储到新集合中
//        3. 遍历打印最终结果

        ArrayList<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("张翠山");
        list.add("张良");
        list.add("王二麻子");
        list.add("谢广坤");
        list.add("张三丰");

        //1.把所有以张开头的元素存储到新集合中
        ArrayList<String> list1 = new ArrayList<>();
        list.forEach(s -> {
            if (s.startsWith("张")) list1.add(s);
        });
        System.out.println(list1);

        //2.把张开头而且长度为3的元素存储到新集合中
        ArrayList<String> list2 = new ArrayList<>();
        list1.forEach(s -> {
            if (s.length() == 3) list2.add(s);
        });
        System.out.println(list2);


        //使用stream流
        list.stream().filter(s -> s.length() == 3 && s.startsWith("张")).forEach(System.out::println);
    }
}

# Stream流的使用步骤

  1. 创建一个Stream流(流水线),并把数据放上去
获取方式 方法名 说明
单列集合 default Stream<E> stream() Collection中的默认方法
双列集合 无法使用
数组 public static<T> Stream<T> stream(T... values) Arrays工具类中的静态方法
一堆零散数据 public static<T> Stream<T> of(T... values) stream接口中的静态方法

# 单列集合获取stream流

package stream;

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

public class StreamDemo {
    public static void main(String[] args) {
        //1.单列集合获取stream流
        ArrayList<String> list3 = new ArrayList<>();
        Collections.addAll(list3, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
        //获取一条流水线 并把数据放在流水线上
        Stream<String> stream = list3.stream();
        //使用终结方法打印以下流水线上的所有数据
        //stream流的每一条数据本质上是一个Consumer数据 hi用匿名内部类依次打印

//        stream.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.println(s);
//            }
//        });
        //简化方法(stream流只能使用一次)
        stream.forEach(System.out::println);
    }
}

# 双列集合获取stream

package stream;

import java.util.*;

public class StreamDemo2 {
    public static void main(String[] args) {
        //双列集合获取stream流
        //在双列集合中不能直接获取stream流 但是可以将双列集合转化为单列集合
        //创建双列集合
        HashMap<String, String> map = new HashMap<>();
        //添加数据
        map.put("001", "张无忌");
        map.put("002", "张翠山");
        map.put("003", "张良");
        map.put("004", "王二麻子");
        map.put("005", "谢广坤");
        map.put("006", "张三丰");

        //第一种方法 获取双列集合中所有的key 并存入一个set集合中 获取stream流(借助keySet)借助keySet
        Stream<String> stream1 = map.keySet().stream();
        //打印流水线中的元素
        stream1.forEach(System.out::println);
        System.out.println("----------------------------------------------------------------------------------------");
        //第二种方法
        //获取双列集合中所有的键值对对象 并存入单列集合中
        Set<Map.Entry<String, String>> set = map.entrySet();
        System.out.println(set);//[001=张无忌, 002=张翠山, 003=张良, 004=王二麻子, 005=谢广坤, 006=张三丰]
        //获取stream流
        Stream<Map.Entry<String, String>> stream2 = set.stream();
        //遍历
        stream2.forEach(System.out::println);
    }
}

# 数组获取stream流

package stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo3 {
    public static void main(String[] args) {
        //数组获取stream流
        String[] arr = {"张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰"};
        Arrays.stream(arr).forEach(System.out::println);
    }
}

# 零散数据获取stream流

package stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo4 {
    public void main(String[] args) {
        //一堆零散的数据获取stream流
        //前提所有放入流水线的数据类型要一致
        Stream.of("张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰").forEach(System.out::println);
    }
}

注意

  1. stream流只能使用一次,使用后流就关闭了,再次使用会报错。
  2. 零散数据获取stream流时,可以传递整个数组,但只能传递引用数据类型的数组,如果传递基本数据类型,是会把整个数组当作一个元素,放到stream流中

# stream流中的中间方法

名称 说明
stream<T> filter(Predicate<? super T> predicate) 过滤数据
stream<T> distinct() 去重,依赖(hashCode()equals()
stream<T> limit(long maxSize) 获取前几个元素
stream<T> skip(long n) 跳过前n个元素
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 合并两个流
stream<T> map(Function<? super T, ? extends R> mapper) 将元素转换成其他形式或提取信息,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

注意

  1. 中间方法返回新的Stream流,原来的stream流只能使用一次,建议使用链式编程
  2. 修改stream流中的数据,不会影响原来集合或者数组中的数据
  3. 使用concat合并两个流时尽量保持两个流的累心一致,否则输出会去两个类的父类类型
package stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo5 {
    public static void main(String[] args) {
        //stream流中的中间方法
//        1. filter() 过滤
        ArrayList<String> list4 = new ArrayList<>();
        Collections.addAll(list4, "张无忌", "张翠山", "张良", "张良", "谢广坤", "张三丰");
        list4.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
//        2. limit() 获取前几个元素
        list4.stream().limit(3).forEach(System.out::println);
//        3. skip() 跳过前几个元素
        list4.stream().skip(3).forEach(System.out::println);
//        4. distinct() 去重
        list4.stream().distinct().forEach(System.out::println);
//        6. 自定义去重
        System.out.println("----------------------------------------------------------------------------------------");
        ArrayList<pople> list5 = new ArrayList<>();
        Collections.addAll(list5, new pople("张无忌", 18), new pople("张三", 18), new pople("张三", 18), new pople("王五", 30));
        list5.stream().distinct().forEach(s -> System.out.println(s.name));

//        7.合并两个流
        System.out.println("----------------------------------------------------------------------------------------");
        ArrayList<String> list6 = new ArrayList<>();
        Collections.addAll(list6, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
        ArrayList<String> list7 = new ArrayList<>();
        Collections.addAll(list7, "张无忌", "张翠山", "张良", "王二麻子", "谢广坤", "张三丰");
        Stream<String> stream3 = Stream.concat(list6.stream(), list7.stream());
        stream3.forEach(System.out::println);

        //8.map 改变流中的数据类型
        System.out.println("----------------------------------------------------------------------------------------");
        ArrayList<String> list8 = new ArrayList<>();
        Collections.addAll(list8, "张无忌-10", "张翠山-20", "张良-30", "王二麻子-40", "谢广坤-50", "张三丰-60");
        list8.stream().map(new Function<String, Integer>() {
            @Override
            //apply(s 代表流中的每一个数据) 返回值表示要转换的类型 并且不能是基本数据类型 必须是引用类型
            public Integer apply(String s) {
                String[] split = s.split("-");
                return parseInt(split[1]);
            }
        }).forEach(System.out::println);

        //简化形式
        list8.stream().map(s -> Integer.parseInt(s.split("-")[1])).forEach(System.out::println);

    }

    static class pople {
        String name;
        int age;

        public pople(String name, int age) {
            this.name = name;
            this.age = age;
        }

        //年龄相同代表重复
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            pople pople = (pople) o;
            return age == pople.age;
        }

        @Override
        public int hashCode() {
            return Objects.hash(age);
        }
    }
}

# stream流的终结方法

名称 说明
void forEach(Consumer<? super T> action) 遍历流中的元素
long count() 统计流中元素个数
toArray() 收集流中的数据,放到数组中
collect(Collector<? super T, A, R> collector) 收集流中的数据放到集合中

package stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo6 {
    public static void main(String[] args) {
        //遍历forEach()
        list8.stream().forEach(System.out::println);
        //统计count()
        System.out.println(list8.stream().count());
        //收集流中的数据放到数组中
        //toArray无形参方法

        Object[] arr2 = list8.stream().toArray();
        System.out.println(Arrays.toString(arr2));

        //带形参方法
        //IntFunction 具体类型的数组
        //IntFunction<? extends T[]> 泛型数组
        //apply:流中数据的个数,要跟数组的长度保持一致
        //apply返回值表示要转换的类型
        //方法体就是创建数组
        //toArray 创建指定类型的数组,
        //底层 会依次得到流里面的每一个数据,并把数据放到数组当中
        //toArray的返回值是一个装着流里面所有数据的数组
        String[] arr3 = list8.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                System.out.println("value = " + value);//value = 6
                //创建具体类型的数组
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(arr3));
        //简化写法
        String[] arr4 = list8.stream().toArray(s -> new String[s]);
        System.out.println(Arrays.toString(arr4));


    }
}

# stream收集方法collect

使用collect函数可以收集流中的数据,放到ListSetMap等集合中。

package stream;

import java.util.*;
import java.util.stream.Stream;

public class StreamDemo7 {
    public static void main(String[] args) {
        //stream收集方法 收集到集合中
        ArrayList<String> list9 = new ArrayList<>();
        Collections.addAll(list9, "张无忌-男-18", "张翠山-男-19", "张良-女-20", "王二麻子-男-21", "谢广坤-男-22", "张三丰-男-23");

        //需求收集所有的男性
        //收集到list集合中
        List<String> list10 = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toList());
        System.out.println(list10);
        //收集到set集合中(set集合不重复)
        Set<String> setList = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toSet());
        System.out.println(setList);
        //收集到map集合中(谁作为键,谁做为值)
        //toMap
        //参数1:键的生成规则
        //参数2:值的生成规则
        Map<String, String> stringMap = list9.stream().filter(s -> s.split("-")[1].equals("男")).collect(Collectors.toMap(s -> s.split("-")[0], s -> s.split("-")[2]));
        System.out.println(stringMap);
    }
}

# stream流综合练习

# 数据过滤

定义一个集合,并添加一些整数 过滤奇数只留下偶数,并把结果收集起来

package stream;

public class StreamDemo8 {
    public static void main(String[] args) {
       ArrayList<Integer> list11 = new ArrayList<>();
       Collections.addAll(list11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
       List<Integer> list12 = list11.stream().filter(s -> s % 2 == 0).toList();
       System.out.println(list12);//[2, 4, 6, 8, 10]
    }
}

创建一个ArrayList集合,并添加一些字符串,字符串前面是姓名后面是年龄 保留年龄大于24的人,并将结果收集到map集合中,姓名为键,年龄为值

package stream;
public class StreamDemo9 {
    public static void main(String[] args) {
       ArrayList<String> list13 = new ArrayList<>();
       Collections.addAll(list13, "张无忌-18", "张翠山-19", "张良-20", "王二麻子-21", "谢广坤-22", "张三丰-23");
       Map<String, Integer> map1 = list13.stream().map(s -> {
          String[] split = s.split("-");
          return new String[]{split[0], split[1]};
       }).filter(s -> parseInt(s[1]) > 18).collect(Collectors.toMap(s -> s[0], s -> parseInt(s[1])));
       System.out.println(map1);
    }
}
上次更新: 1/10/2025, 4:57:33 PM