Java—Stream流

发布于:2025-06-18 ⋅ 阅读:(20) ⋅ 点赞:(0)

一.引言

现在有个任务,如下所示:

ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");

将这些数据中姓张的,并且名字是三个字的单独放一个集合打印出来

我们可以使用增强for循环来完成遍历和筛选,如下代码所示:

        ArrayList<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        //把所有张开头的人加到一个集合中
        ArrayList<String> arrayList = new ArrayList<>();
        for (String name : list) {
            if (name.startsWith("张")){
                arrayList.add(name);
            }
        }
        //把张姓的三字人名加到一个集合中
        ArrayList<String> list1 = new ArrayList<>();
        for (String s : arrayList) {
            int length = s.length();
            if (length == 3){
                list1.add(s);
            }
        }
        System.out.println(list1);

 可见使用增强for循环来遍历略显复杂,我们接下来使用Stream流来进行遍历筛选

 ArrayList<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
 list.stream()
     .filter(name->name.startsWith("张"))
     .filter(name->name.length() == 3)
     .forEach(name-> System.out.println(name));

使用Stream流来遍历,大大简化了代码复杂度

二.获取Stream流

Stream流的思想就相当于一个流水线一样,将数据放在流水线上层层处理,最终输出

使用Stream流步骤有三个:

  • 获取Stream流,并将数据装到流里
  • 使用中间操作处理流
  • 使用终结操作处理流

下面逐一说说这三个步骤

首先是获取Stream流,针对不同类型的集合有不同的方式

  • 单列集合  default Stream<E> stream()  Collection中默认的方法
ArrayList<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
//单列集合获取Stream流
Stream<String> stream = list.stream();
stream.forEach(name-> System.out.println(name));
  • 双列集合  没有直接能获取Stream流的方式,需要借助keySet和entrySet
 Map<String, Integer> map = Map.of("a", 111, "b", 222, "c", 333);
 //方式一:获取map的key
 map.keySet().stream().forEach(key-> System.out.println(key));
 //方式二:获取map的key和value
 map.entrySet().stream().forEach(s-> System.out.println(s));
  •  数组  public static <T> Stream(T[] array)  Arrays工具类中的静态方法
String[] str = {"a","b","c","d","e"};
Arrays.stream(str).forEach(s-> System.out.println(s));
  • 一堆零散数据  public static <T> Stream<T> of(T...values)  Stream接口中的静态方法
Stream.of("1","2","3").forEach(s-> System.out.println(s));

三.Stream常见中间方法

  • filter方法——过滤不需要的数据

这个例子可以看看目录一中的代码

  • limit方法——获取流中前几个元素
List<String> list = Arrays.asList("a-12", "b-13", "c-20");
//获取前两个元素
list.stream().limit(2).forEach(s-> System.out.println(s));
  • skip方法——跳过前几个元素
List<String> list = Arrays.asList("a-12", "b-13", "c-20");
//跳过前一个元素
list.stream().skip(1).forEach(s-> System.out.println(s));
  • distinct方法——元素去重(依赖于hashcode和eqauls方法,需要重写)
List<String> list = Arrays.asList("a-12", "b-13", "c-20", "c-20");
//元素去重
list.stream().distinct().forEach(s-> System.out.println(s));
  • map方法——转换流中的数据类型
List<String> list = Arrays.asList("a-12", "b-13", "c-20", "c-20");
//对元素进行筛选,留下每个元素的数字部分,并且转换成整型
list.stream()
    .map(s->Integer.parseInt(s.split("-")[1]))
    .forEach(s-> System.out.println(s));

四.Stream常见终结方法

  • forEach方法——获取每一个元素

看看上面的例子里的代码,有关于forEach的使用

  • toArray方法——将流转换成数组
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
Object[] array = list.stream().toArray();

toArray()有两种重载形式,上面这种不需要参数的方法,它返回一个Object类型的数组,如果我们要想返回具体的类型,需要使用带参数的toArray方法,如下所示

String[] strings = list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
            //参数value表示数组的长度
                return new String[value];
            }
        });

这个方法的参数,需要一个具体类型的数组,如下所示,表示泛型是一个具体类型的数组

刚刚上面的代码是使用匿名内部类实现的,我们现在看看Lambda表达式的形式,如下所示

list.stream().toArray(value->new String[value]);
  • count方法——返回元素的个数
 long count = list.stream().count();
  • collect方法——收集元素并放到集合中
//收集数据并将其存放进List中
List<String> collect1 = list.stream().collect(Collectors.toList());
//收集数据并将其存放进Set中
Set<String> collect2 = list.stream().collect(Collectors.toSet());
//收集数据并将其存放进Map中
Map<String, String> collect = list.stream()
         .collect(Collectors.toMap(
                k -> k.split("-")[0], v -> v.split("-")[1]
                )
         );

主要讲一下这个toMap方法,有两个参数,第一个参数是Map的key,第二个是value,这个方法中的匿名内部类和刚刚上面讲的中间方法Map的匿名内部类是一样的


网站公告

今日签到

点亮在社区的每一天
去签到