java Stream

1.简介

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

2.构建Stream流

集合类型通过.Stream()方法转换为Stream流

List<String> list= new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("郭七");
        list.add("王勃");
Stream<String> stream = list.stream();

3.Stream流的常用操作

(1)forEach循环

通过forEach()方法来遍历流中的数据,属于终结方法,后面不能再调用别的流操作

List<String> list= new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("郭七");
        list.add("王勃");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);//打印流中的数据

结果: 张三

​ 李四

​ 王五

​ 赵六

​ 郭七

​ 王勃

forEach() 方法接收的是一个 Consumer(Java 8 新增的一个函数式接口,接受一个输入参数并且无返回的操作)类型的参数,类名 :: 方法名是 Java 8 引入的新语法,System.out 返回 PrintStream 类,println 方法你应该知道是打印的。

(2)filter过滤

通过 filter() 方法可以从流中筛选出我们想要的元素

List<String> list= new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("郭七");
        list.add("王勃");
Stream<String> stream = list.stream();
stream.filter(name->name.startsWith("王"))//过滤流中"王"开头的数据
		.forEach(System.out::println);//打印流中的数据

结果:王五

​ 王勃

filter() 方法接收的是一个 Predicate(Java 8 新增的一个函数式接口,接受一个输入参数返回一个布尔值结果)类型的参数,因此,我们可以直接将一个 Lambda 表达式传递给该方法,比如说 element -> element.startsWith("王") 就是筛选出“王”开头的字符串。

(3)map映射

如果想通过某种操作把一个流中的元素转化成新的流中的元素,可以使用 map() 方法。

 List<String> list= new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("郭七");
        list.add("王勃");
Stream<String> stream = list.stream();
stream.map(name->name=name.substring(1))//将姓名映射为不带姓的名字
        .forEach(System.out::println);//打印流中的数据

结果:三

​ 四

​ 五

​ 六

(4)Match匹配

Stream 类提供了三个方法可供进行元素匹配,它们分别是:

  • anyMatch(),只要有一个元素匹配传入的条件,就返回 true。
  • allMatch(),只有有一个元素不匹配传入的条件,就返回 false;如果全部匹配,则返回 true。
  • noneMatch(),只要有一个元素匹配传入的条件,就返回 false;如果全部匹配,则返回 true。
public class MatchStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰伦");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");

        boolean  anyMatchFlag = list.stream().anyMatch(element -> element.contains("王"));
        boolean  allMatchFlag = list.stream().allMatch(element -> element.length() > 1);
        boolean  noneMatchFlag = list.stream().noneMatch(element -> element.endsWith("沉"));
        System.out.println(anyMatchFlag);
        System.out.println(allMatchFlag);
        System.out.println(noneMatchFlag);
    }
}

因为“王力宏”以“王”字开头,所以 anyMatchFlag 应该为 true;因为“周杰伦”、“王力宏”、“陶喆”、“林俊杰”的字符串长度都大于 1,所以 allMatchFlag 为 true;因为 4 个字符串结尾都不是“沉”,所以 noneMatchFlag 为 true。

程序输出的结果如下所示:

true
true
true
(5)reduce组合

reduce() 方法的主要作用是把 Stream 中的元素组合起来,它有两种用法:

  • Optional reduce(BinaryOperator accumulator)

没有起始值,只有一个参数,就是运算规则,此时返回 Optional

  • T reduce(T identity, BinaryOperator accumulator)

有起始值,有运算规则,两个参数,此时返回的类型和起始值类型一致。

来看下面这个例子。

public class ReduceStreamDemo {
    public static void main(String[] args) {
        Integer[] ints = {0, 1, 2, 3};
        List<Integer> list = Arrays.asList(ints);

        Optional<Integer> optional = list.stream().reduce((a, b) -> a + b);
        Optional<Integer> optional1 = list.stream().reduce(Integer::sum);
        System.out.println(optional.orElse(0));
        System.out.println(optional1.orElse(0));

        int reduce = list.stream().reduce(6, (a, b) -> a + b);
        System.out.println(reduce);
        int reduce1 = list.stream().reduce(6, Integer::sum);
        System.out.println(reduce1);
    }
}

运算规则可以是 Lambda 表达式(比如 (a, b) -> a + b),也可以是类名::方法名(比如 Integer::sum)。

程序运行的结果如下所示:

6
6
12
12

0、1、2、3 在没有起始值相加的时候结果为 6;有起始值 6 的时候结果为 12。

4.Stream流转换

既然可以把集合或者数组转成流,那么也应该有对应的方法,将流转换回去——collect() 方法就满足了这种需求。

public class CollectStreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("周杰伦");
        list.add("王力宏");
        list.add("陶喆");
        list.add("林俊杰");

        List<Integer> list1 = list.stream().map(String::length).collect(Collectors.toList());
        System.out.println(list1);

        String str = list.stream().collect(Collectors.joining(", ")).toString();
        System.out.println(str);
    }
}
posted @ 2023-03-01 14:13  猫的烦恼  阅读(44)  评论(0编辑  收藏  举报