Java中Stream流详解

概要

✨介绍

Java中的Stream是Java 8引入的一种新的API,用于处理集合或数组中的数据,提供了一种简洁且高效的方式来进行各种操作,如过滤、排序、映射、汇总等。Stream不存储数据,它更像是一个高级迭代器,通过一系列流水线操作来处理数据。Stream操作可以分为两类:中间操作和终端操作

🍁特点

  • 惰性求值 (Lazy Evaluation):Stream中的操作是惰性执行的,只有在终止操作执行时,才会实际计算结果。
  • 不可变性 (Immutability):Stream是不可变的,每次对Stream的操作都会返回一个新的Stream,而不会修改原始数据源。
  • 无存储 (No Storage):Stream不会存储数据,数据存储在数据源中。

💪操作类型

  • 中间操作 (Intermediate Operations):返回一个新的Stream,允许多个操作链式调用。这些操作都是惰性执行的,直到执行终止操作。

常见的中间操作包括:filter(), map(), sorted(), distinct(), limit(), skip(), peek()等。

  • 终止操作 (Terminal Operations):触发Stream的处理并生成结果。终止操作会关闭Stream,使得Stream无法再被使用。

常见的终止操作包括:forEach(), collect(), reduce(), count(), min(), max(), anyMatch(), allMatch(), noneMatch()等。

🐜优缺点

优点:

  1. 代码简洁性与可读性:Stream 提供了声明式的编程方式,使得代码更简洁、优雅。可以通过链式调用将复杂的操作步骤清晰地表达出来,减少了样板代码(如循环和条件判断)的使用。
  2. 函数式编程支持:Stream 强化了Java对函数式编程的支持。开发者可以将Lambda表达式与Stream结合,使用map、filter、reduce等操作处理数据,这种方式更加直观且容易维护。
  3. 并行处理能力:Stream 支持并行流(parallelStream),允许在多核处理器上并行处理数据,提升处理性能,特别适合大规模数据处理的场景。
  4. 惰性求值:Stream 的惰性求值特性可以优化性能。只有在终止操作执行时,Stream 才会真正执行操作。这使得可以将多个中间操作组合起来,并且只需遍历数据源一次,减少不必要的计算。
  5. 流畅的API设计:Stream API 设计非常流畅,提供了多种常用操作,可以很方便地组合这些操作来实现各种复杂的数据处理逻辑。

缺点:

  1. 调试困难:由于Stream使用了链式调用和Lambda表达式,调试过程比传统的for循环复杂得多。特别是在链式操作中出现错误时,定位问题可能较为困难。
  2. 性能开销:虽然Stream可以通过并行处理提升性能,但在某些场景下,它的性能可能低于传统的循环。例如,在涉及大量对象创建或短小集合的场景中,Stream的惰性求值和中间对象的创建可能带来额外的性能开销。
  3. 可读性问题:虽然Stream可以使代码更加简洁,但过度使用或在不适合的场合使用Stream可能导致代码过于复杂,降低可读性,特别是对于不熟悉Stream的开发者而言。
  4. 资源消耗:在某些情况下,Stream 可能导致较高的内存消耗。例如,如果在一个非常大的集合上使用复杂的流操作链,可能会占用大量内存,甚至导致OutOfMemoryError。
  5. 不适合所有场景:Stream 更适合处理无状态的、不可变的数据操作。对于需要频繁修改数据或需要处理具有状态的操作,传统的迭代方法可能更为合适。
package com.stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
* 需求:找出姓张,并且是3个字的名字,存入到一个新集合中
*/
public class Demo {
   
    public static void main(String[] args) {
   
        ArrayList<String> names = new ArrayList<>();
        Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张三", "韦一笑");

        // 方案一:传统遍历
        List<String> list = new ArrayList<>();
        for (String name : names) {
   
            if (name.startsWith("张") && name.length() == 3) {
   
                list.add(name);
            }
        }
        System.out.println(list); // [张三丰, 张无忌]


        // 方案二:Stream
        List<String> list2 = names.stream()
                .filter(name -> name.startsWith("张") && name.length() == 3)
                .collect(Collectors.toList());
        System.out.println(list2); // [张三丰, 张无忌]
    }
}

获取Steam流

获取List集合的Stream流

ArrayList<String> names = new ArrayList<>();
Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张三", "韦一笑");
Stream<String> stream = names.stream();

获取Set集合的Stream流

Set<String> set = new HashSet<>();
Collections.addAll(set, "九阳神功", "乾坤大挪移", "九阴白骨爪", "峨眉剑法");
Stream<String> stream1 = set.stream();

获取Map集合的流

Map<String, Integer> map = new HashMap<>();
map.put("李白", 521);
map.put("杜甫", 412);
map.put("白居易", 243);
map.put("陶渊明", 156);

// map keys 的 Stream
Set<String> strings = map.keySet();
Stream<String> stream2 = strings.stream();

// Map values 的 Stream
Collection<Integer> values = map.values();
Stream<Integer> stream3 = values.stream();

Set<Map.Entry
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值