Stream API

        Stream 是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

        Stream 和 Collection 集合的区别:Collection 是一种静态的内存数据结构, 讲的是数据,而 Stream 是有关计算的,讲的是计算。前者是主要面向内存, 存储在内存中,后者主要是面向 CPU,通过 CPU 实现计算。

  • Stream 自己不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream。
  • Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。即一旦执行终止操作,就执行中间操作链,并产生结果。
  • Stream 一旦执行了终止操作,就不能再调用其它中间操作或终止操作了。

Stream 的操作三个步骤

1- 创建 Stream:一个数据源(如:集合、数组),获取一个流

Integer[] nums = {11, 2, 4, 7, 0, 1, 1, 7};

// 方式一:通过集合
List<Integer> list = Arrays.asList(nums);
// 顺序流
Stream<Integer> stream = list.stream();
// 并行流
Stream<Integer> stream1 = list.parallelStream();

// 方式二:通过数组
Stream<Integer> stream2 = Arrays.stream(nums);

// 方式三:通过Stream的of()
Stream<String> stream3 = Stream.of("A", "B", "D", "C");

2- 中间操作:每次处理都会返回一个持有结果的新 Stream,即中间操作的方法 返回值仍然是 Stream 类型的对象。因此中间操作可以是个操作链,可对数据源的数据进行 n 次处理,但是在终结操作前,并不会真正执行。

        // 筛选与切片
        // filter() 过滤
        stream.filter(num -> num > 3).forEach(System.out :: println);   // 11, 4, 7, 7
        System.out.println();
        // limit() 截断,使元素不超过给定数量
        // stream.limit(2).forEach(System.out :: println); // 错误,上一行forEach已将stream终止
        list.stream().filter(num -> num > 3).limit(2).forEach(System.out :: println);   // 11, 4
        System.out.println();
        // skip() 跳过前n个元素,若流中元素不足n,返回一个空流
        list.stream().skip(2).forEach(System.out :: println);   // 4, 7, 0, 1, 1, 7
        System.out.println();
        // distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
        list.stream().distinct().forEach(System.out :: println);    // 11, 2, 4, 7, 0, 1
        System.out.println();

        // 映射
        // map(Function f) 接收一个函数作为参数,将元素转换成其他形式或提取信息,
        // 该函数会被应用到每个元素上,并将其映射成一个新的元素
        stream3.map(String :: toLowerCase).forEach(System.out :: println); // a, b, d, c
        System.out.println();

        // 排序
        // 自然排序
        list.stream().sorted().forEach(System.out :: println); // 0, 1, 1, 2, 4, 7, 7, 11
        System.out.println();
        // 定制排序
        list.stream().sorted((o1, o2) -> o2 - o1).forEach(System.out :: println); // 11, 7, 7, 4, 2, 1, 1, 0

3- 终止操作(终端操作):终止操作的方法返回值类型就不再是 Stream 了,因此 一旦执行终止操作,就结束整个 Stream 操作了。一旦执行终止操作,就执行中间操作链,最终产生结果并结束 Stream。

        // 匹配与查找
        // allMatch(Predicate p) 检查是否匹配所有元素
        boolean a1 = list.stream().allMatch(num -> num > 0);
        System.out.println(a1); // false
        // anyMatch(Predicate p) 检查是否匹配至少一个元素
        a1 = list.stream().anyMatch(num -> num > 0);
        System.out.println(a1); // true
        // findFirst() 返回第一个元素
        System.out.println(list.stream().findFirst()); // Optional[11]
        System.out.println(list.stream().findFirst().get());    // 11
        // count 返回流中的总个数
        System.out.println(list.stream().count()); // 8
        // max(Comparator c) 返回流中最大值(排序完最右边的值)
        System.out.println(list.stream().max((o1, o2) -> o1 - o2)); // Optional[11]
        System.out.println(list.stream().max((o1, o2) -> o2 - o1)); // Optional[0]
        // min(Comparator c) 返回流中最小值
        System.out.println(list.stream().min((o1, o2) -> o1 - o2)); // Optional[0]
        System.out.println(list.stream().min((o1, o2) -> o2 - o1)); // Optional[11]
        // forEach(Consumer c) 内部迭代
        list.stream().forEach(System.out :: println); // 11, 2, 4, 7, 0, 1, 1, 7

        // 归约
        // reduce(T identity, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T 
        System.out.println(list.stream().reduce(0, (o1, o2) -> o1 + o2));   // list中数的和,identity为初始值 33
        
        // 收集
        // collect(Collector c) 将流转换为其他形式。接收一个 Collector 接口的实现,用于给 Stream 中元素做汇总的方法
        List<Integer> list2 = list.stream().collect(Collectors.toList());
        System.out.println(list2);  // [11, 2, 4, 7, 0, 1, 1, 7]
        Set<Integer> set = list.stream().collect(Collectors.toSet());
        System.out.println(set);    // [0, 1, 2, 4, 7, 11]
        // toCollection Collector<T, ?, C> 把流中元素收集到创建的集合 
        Collection<Integer> co = list.stream().collect(Collectors.toCollection(ArrayList::new));
        System.out.println(co); // [11, 2, 4, 7, 0, 1, 1, 7]
        // counting Collector<T, ?, Long> 计算流中元素的个数
        System.out.println(list.stream().collect(Collectors.counting()));   // 8
        // summingInt Collector<T, ?, Integer> 对流中元素的整数属性求和 
        // averagingInt Collector<T, ?, Double> 计算流中元素 Integer 属性的平均值
        // summarizingInt Collector<T, ?, IntSummaryStatistics> 收集流中 Integer 属性的统计值。如:平均值 
        // joining Collector<CharSequence, ?, String> 连接流中每个字符串
        // maxBy Collector<T, ?, Optional> 根据比较器选择最大值 
        // minBy Collector<T, ?, Optional> 根据比较器选择最小值 
        // reducing Collector<T, ?, Optional> 从一个作为累加器的初始值开始,利用BinaryOperator 与流中元素逐个结合,从而归约成单个值 
        // collectingAndThen Collector<T,A,RR> 包裹另一个收集器,对其结果转换函数 
        // groupingBy Collector<T, ?, Map<K, List>> 根据某属性值对流分组,属性为K,结果为 V 
        // partitioningBy Collector<T, ?, Map<Boolean, List>> 根据 true 或 false 进行分区 
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值