温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java stream如何使用

发布时间:2022-10-24 11:41:08 来源:亿速云 阅读:185 作者:iii 栏目:编程语言

Java Stream 如何使用

目录

  1. 引言
  2. Stream 简介
  3. 创建 Stream
  4. 中间操作
  5. 终端操作
  6. 并行流
  7. Stream 的性能考虑
  8. Stream 与集合的区别
  9. Stream 的常见用例
  10. Stream 的局限性
  11. 总结

引言

Java 8 引入了 Stream API,它提供了一种高效且声明式的方式来处理集合数据。Stream 允许开发者以函数式编程的风格处理数据,使得代码更加简洁、易读。本文将详细介绍 Stream 的使用方法,包括如何创建 Stream、中间操作、终端操作、并行流、性能考虑、与集合的区别、常见用例以及局限性。

Stream 简介

Stream 是 Java 8 引入的一个新抽象,它允许开发者以声明式的方式处理数据集合。Stream 不是数据结构,它不存储数据,而是对数据进行操作。Stream 的操作可以分为两类:中间操作和终端操作。

  • 中间操作:返回一个新的 Stream,可以链式调用多个中间操作。
  • 终端操作:触发 Stream 的处理并返回结果,终端操作执行后,Stream 不能再被使用。

创建 Stream

从集合创建 Stream

最常见的创建 Stream 的方式是从集合中创建。Java 8 为 Collection 接口添加了 stream()parallelStream() 方法,用于创建顺序流和并行流。

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
Stream<String> parallelStream = list.parallelStream();

从数组创建 Stream

可以使用 Arrays.stream() 方法从数组创建 Stream

String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);

使用 Stream.of() 创建 Stream

Stream.of() 方法可以接受任意数量的参数,并返回一个包含这些参数的 Stream

Stream<String> stream = Stream.of("a", "b", "c");

使用 Stream.iterate() 创建 Stream

Stream.iterate() 方法可以生成一个无限流,它接受一个初始值和一个函数,函数用于生成下一个值。

Stream<Integer> stream = Stream.iterate(0, n -> n + 2);

使用 Stream.generate() 创建 Stream

Stream.generate() 方法可以生成一个无限流,它接受一个 Supplier 函数,用于生成流中的元素。

Stream<Double> stream = Stream.generate(Math::random);

从文件创建 Stream

可以使用 Files.lines() 方法从文件中创建 Stream

Stream<String> lines = Files.lines(Paths.get("file.txt"));

中间操作

中间操作是 Stream 的核心部分,它们返回一个新的 Stream,允许链式调用多个操作。常见的中间操作包括 filtermapflatMapdistinctsortedpeek 等。

filter

filter 方法用于过滤 Stream 中的元素,它接受一个 Predicate 函数,返回一个包含满足条件元素的 Stream

Stream<String> stream = Stream.of("a", "b", "c");
Stream<String> filteredStream = stream.filter(s -> s.startsWith("a"));

map

map 方法用于将 Stream 中的每个元素映射为另一个元素,它接受一个 Function 函数,返回一个包含映射后元素的 Stream

Stream<String> stream = Stream.of("a", "b", "c");
Stream<String> mappedStream = stream.map(String::toUpperCase);

flatMap

flatMap 方法用于将 Stream 中的每个元素映射为一个 Stream,然后将这些 Stream 合并为一个 Stream

Stream<List<String>> stream = Stream.of(
    Arrays.asList("a", "b"),
    Arrays.asList("c", "d")
);
Stream<String> flatMappedStream = stream.flatMap(List::stream);

distinct

distinct 方法用于去除 Stream 中的重复元素。

Stream<String> stream = Stream.of("a", "b", "a");
Stream<String> distinctStream = stream.distinct();

sorted

sorted 方法用于对 Stream 中的元素进行排序。

Stream<String> stream = Stream.of("c", "a", "b");
Stream<String> sortedStream = stream.sorted();

peek

peek 方法用于对 Stream 中的每个元素执行操作,通常用于调试。

Stream<String> stream = Stream.of("a", "b", "c");
Stream<String> peekedStream = stream.peek(System.out::println);

终端操作

终端操作是 Stream 的最后一步,它触发 Stream 的处理并返回结果。常见的终端操作包括 forEachcollectreducecountminmaxanyMatchallMatchnoneMatchfindFirstfindAny 等。

forEach

forEach 方法用于对 Stream 中的每个元素执行操作。

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

collect

collect 方法用于将 Stream 中的元素收集到一个集合中。

Stream<String> stream = Stream.of("a", "b", "c");
List<String> list = stream.collect(Collectors.toList());

reduce

reduce 方法用于将 Stream 中的元素归约为一个值。

Stream<Integer> stream = Stream.of(1, 2, 3);
Optional<Integer> sum = stream.reduce(Integer::sum);

count

count 方法用于返回 Stream 中元素的数量。

Stream<String> stream = Stream.of("a", "b", "c");
long count = stream.count();

min

min 方法用于返回 Stream 中的最小元素。

Stream<Integer> stream = Stream.of(1, 2, 3);
Optional<Integer> min = stream.min(Integer::compareTo);

max

max 方法用于返回 Stream 中的最大元素。

Stream<Integer> stream = Stream.of(1, 2, 3);
Optional<Integer> max = stream.max(Integer::compareTo);

anyMatch

anyMatch 方法用于判断 Stream 中是否有元素满足条件。

Stream<String> stream = Stream.of("a", "b", "c");
boolean anyMatch = stream.anyMatch(s -> s.startsWith("a"));

allMatch

allMatch 方法用于判断 Stream 中的所有元素是否都满足条件。

Stream<String> stream = Stream.of("a", "b", "c");
boolean allMatch = stream.allMatch(s -> s.startsWith("a"));

noneMatch

noneMatch 方法用于判断 Stream 中是否没有元素满足条件。

Stream<String> stream = Stream.of("a", "b", "c");
boolean noneMatch = stream.noneMatch(s -> s.startsWith("d"));

findFirst

findFirst 方法用于返回 Stream 中的第一个元素。

Stream<String> stream = Stream.of("a", "b", "c");
Optional<String> first = stream.findFirst();

findAny

findAny 方法用于返回 Stream 中的任意一个元素。

Stream<String> stream = Stream.of("a", "b", "c");
Optional<String> any = stream.findAny();

并行流

Stream 支持并行处理,可以通过 parallel() 方法将顺序流转换为并行流。并行流利用多核处理器的优势,可以显著提高处理速度。

Stream<String> stream = Stream.of("a", "b", "c");
Stream<String> parallelStream = stream.parallel();

并行流的注意事项

  • 线程安全:并行流操作可能会涉及多个线程,因此需要确保操作是线程安全的。
  • 性能开销:并行流的创建和管理需要额外的开销,对于小数据集,顺序流可能更快。
  • 顺序性:并行流的处理顺序是不确定的,如果需要保持顺序,可以使用 forEachOrdered 方法。

Stream 的性能考虑

Stream 的性能受多种因素影响,包括数据量、操作类型、并行处理等。以下是一些性能优化的建议:

  • 避免不必要的中间操作:每个中间操作都会创建一个新的 Stream,增加额外的开销。
  • 使用并行流:对于大数据集,并行流可以显著提高处理速度。
  • 选择合适的终端操作:不同的终端操作有不同的性能特点,选择合适的操作可以提高性能。

Stream 与集合的区别

Stream 和集合都是用于处理数据的工具,但它们有一些重要的区别:

  • 数据存储:集合存储数据,而 Stream 不存储数据。
  • 数据处理:集合支持增删改查操作,而 Stream 只支持数据处理操作。
  • 延迟执行Stream 的操作是延迟执行的,只有在终端操作触发时才会执行。
  • 不可重复使用Stream 只能被使用一次,终端操作执行后,Stream 不能再被使用。

Stream 的常见用例

过滤和映射

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> result = names.stream()
    .filter(name -> name.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

归约操作

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
    .reduce(0, Integer::sum);

分组和分区

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Map<Integer, List<String>> grouped = names.stream()
    .collect(Collectors.groupingBy(String::length));

并行处理

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> result = names.parallelStream()
    .filter(name -> name.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

Stream 的局限性

尽管 Stream 提供了强大的数据处理能力,但它也有一些局限性:

  • 不可重复使用Stream 只能被使用一次,终端操作执行后,Stream 不能再被使用。
  • 调试困难:由于 Stream 的操作是延迟执行的,调试时可能难以追踪问题。
  • 性能开销Stream 的操作需要额外的开销,对于小数据集,传统的循环可能更快。

总结

Stream 是 Java 8 引入的一个强大工具,它提供了一种高效且声明式的方式来处理集合数据。通过 Stream,开发者可以以函数式编程的风格处理数据,使得代码更加简洁、易读。本文详细介绍了 Stream 的使用方法,包括如何创建 Stream、中间操作、终端操作、并行流、性能考虑、与集合的区别、常见用例以及局限性。希望本文能帮助你更好地理解和使用 Stream

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI