Java --- Stream

Java 8 引入了 Stream API,它提供了一种高效且易于表达的方式来处理集合数据。Stream API 允许你以声明式的方式处理数据,支持函数式编程风格,使得代码更加简洁和易读。以下是关于 Java Stream 流的详细介绍:

1. Stream 流的基本概念

Stream 流是对集合(Collection)数据进行操作的抽象,它可以进行各种操作,如过滤、映射、排序、聚合等。Stream 流不是数据结构,它不存储数据,而是通过管道(pipeline)的方式对数据进行处理。

2. Stream 流的创建

2.1 从集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
2.2 从数组创建
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
2.3 使用 Stream.of 创建
Stream<String> stream = Stream.of("a", "b", "c");
2.4 创建无限流
Stream<Integer> infiniteStream = Stream.iterate(0, n -> n + 2);

3. Stream 流的操作

Stream 流的操作分为两种类型:中间操作(intermediate operations)和终端操作(terminal operations)。

3.1 中间操作

中间操作返回一个新的 Stream 流,可以进行链式调用。常见的中间操作包括:

  • filter:过滤元素
  • map:映射元素
  • flatMap:扁平化映射
  • distinct:去重
  • sorted:排序
  • peek:调试操作
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
    .filter(name -> name.length() > 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());
3.2 终端操作

终端操作触发流的处理并产生结果。常见的终端操作包括:

  • forEach:遍历元素
  • collect:收集元素到集合
  • reduce:聚合操作
  • count:计数
  • anyMatch:任意匹配
  • allMatch:全部匹配
  • noneMatch:无匹配
  • findFirst:查找第一个元素
  • findAny:查找任意元素
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
    .filter(n -> n % 2 == 0)
    .reduce(0, Integer::sum);

4. Stream 流的特性

4.1 惰性求值

Stream 流的操作是惰性求值的,即直到终端操作时才会真正执行。这样可以提高性能,避免不必要的计算。

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5)
    .filter(n -> {
        System.out.println("Filter: " + n);
        return n % 2 == 0;
    });

System.out.println("Before terminal operation");
stream.forEach(System.out::println);
4.2 并行流

Stream 流支持并行处理,通过 parallelStream 方法可以创建并行流,利用多核处理器提高处理速度。

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.parallelStream()
    .filter(n -> n % 2 == 0)
    .reduce(0, Integer::sum);

5. Stream 流的示例

5.1 过滤和映射
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
    .filter(name -> name.length() > 3)
    .map(String::toUpperCase)
    .collect(Collectors.toList());
5.2 去重和排序
List<Integer> numbers = Arrays.asList(5, 3, 1, 4, 2, 3, 5);
List<Integer> distinctSortedNumbers = numbers.stream()
    .distinct()
    .sorted()
    .collect(Collectors.toList());
5.3 聚合操作
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
    .filter(n -> n % 2 == 0)
    .reduce(0, Integer::sum);
5.4 分组和统计
List<Person> people = Arrays.asList(
    new Person("Alice", 25),
    new Person("Bob", 30),
    new Person("Charlie", 25)
);

Map<Integer, List<Person>> peopleByAge = people.stream()
    .collect(Collectors.groupingBy(Person::getAge));

Map<Integer, Long> countByAge = people.stream()
    .collect(Collectors.groupingBy(Person::getAge, Collectors.counting()));

6. Stream 流的注意事项

6.1 避免修改流的数据源

在流操作过程中,应避免修改流的数据源,否则可能导致不确定的行为。

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Stream<String> stream = list.stream();
list.add("d"); // 避免在流操作过程中修改数据源
stream.forEach(System.out::println);
6.2 避免多次使用同一个流

流一旦被终端操作消费,就不能再次使用。

Stream<String> stream = Stream.of("a", "b", "c");
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出 IllegalStateException

7. 总结

Java Stream API 提供了一种强大且灵活的方式来处理集合数据。通过 Stream 流,你可以以声明式的方式进行数据处理,支持惰性求值和并行处理,使得代码更加简洁和高效。希望这些内容能够帮助你更好地理解和应用 Java Stream 流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要重新演唱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值