Stream流式编程

如何创建 Stream 对象

从集合创建:我们可以通过调用集合的 stream() 方法来创建一个 Stream 对象。例如:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> stream = numbers.stream();

从数组创建:Java 8 引入了 Arrays 类的 stream() 方法,我们可以使用它来创建一个 Stream 对象。例如:

String[] names = {"Alice", "Bob", "Carol"};
Stream<String> stream = Arrays.stream(names);

通过 Stream.of() 创建:我们可以使用 Stream.of() 方法直接将一组元素转换为 Stream 对象。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);

通过 Stream.builder() 创建:如果我们不确定要添加多少个元素到 Stream 中,可以使用 Stream.builder() 创建一个 Stream.Builder 对象,并使用其 add() 方法来逐个添加元素,最后调用 build() 方法生成 Stream 对象。例如:

Stream.Builder<String> builder = Stream.builder();
builder.add("Apple");
builder.add("Banana");
builder.add("Cherry");
Stream<String> stream = builder.build();

从 I/O 资源创建:Java 8 引入了一些新的 I/O 类(如 BufferedReaderFiles 等),它们提供了很多方法来读取文件、网络流等数据。这些方法通常返回一个 Stream 对象,可以直接使用。例如:

Path path = Paths.get("data.txt");
try (Stream<String> stream = Files.lines(path)) {
    // 使用 stream 处理数据
} catch (IOException e) {
    e.printStackTrace();
}

通过生成器创建:除了从现有的数据源创建 Stream,我们还可以使用生成器来生成元素。Java 8 中提供了 Stream.generate() 方法和 Stream.iterate() 方法来创建无限 Stream。例如:

Stream<Integer> stream = Stream.generate(() -> 0); // 创建一个无限流,每个元素都是 0
Stream<Integer> stream = Stream.iterate(0, n -> n + 1); // 创建一个无限流,从 0 开始递增

需要注意的是,Stream 对象是一种一次性使用的对象,它只能被消费一次。一旦对 Stream 执行了终止操作(如收集结果、遍历元素),Stream 就会被关闭,后续无法再使用。因此,在使用 Stream 时,需要根据需要重新创建新的 Stream 对象。

常用的 Stream 操作方法

过滤(Filter):filter() 方法接受一个 Predicate 函数作为参数,用于过滤 Stream 中的元素。只有满足 Predicate 条件的元素会被保留下来。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> filteredStream = stream.filter(n -> n % 2 == 0); // 过滤出偶数

映射(Map):map() 方法接受一个 Function 函数作为参数,用于对 Stream 中的元素进行映射转换。对每个元素应用函数后的结果会构成一个新的 Stream。例如:

Stream<String> stream = Stream.of("apple", "banana", "cherry");
Stream<Integer> mappedStream = stream.map(s -> s.length()); // 映射为单词长度

扁平映射(FlatMap):flatMap() 方法类似于 map() 方法,不同之处在于它可以将每个元素映射为一个流,并将所有流连接成一个流。这主要用于解决嵌套集合的情况。例如:

List<List<Integer>> nestedList = Arrays.asList(
    Arrays.asList(1, 2),
    Arrays.asList(3, 4),
    Arrays.asList(5, 6)
);
Stream<Integer> flattenedStream = nestedList.stream().flatMap(List::stream); // 扁平化为一个流

截断(Limit):limit() 方法可以限制 Stream 的大小,只保留前 n 个元素。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> limitedStream = stream.limit(3); // 只保留前 3 个元素

跳过(Skip):skip() 方法可以跳过 Stream 中的前 n 个元素,返回剩下的元素组成的新 Stream。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> skippedStream = stream.skip(2); // 跳过前 2 个元素

排序(Sorted):sorted() 方法用于对 Stream 中的元素进行排序,默认是自然顺序排序。还可以提供自定义的 Comparator 参数来指定排序规则。例如:

Stream<Integer> stream = Stream.of(5, 2, 4, 1, 3);
Stream<Integer> sortedStream = stream.sorted(); // 自然顺序排序

去重(Distinct):distinct() 方法用于去除 Stream 中的重复元素,根据元素的 equals() 和 hashCode() 方法来判断是否重复。例如:

Stream<Integer> stream = Stream.of(1, 2, 2, 3, 3, 3);
Stream<Integer> distinctStream = stream.distinct(); // 去重

汇总(Collect):collect() 方法用于将 Stream 中的元素收集到结果容器中,如 List、Set、Map 等。可以使用预定义的 Collectors 类提供的工厂方法来创建收集器,也可以自定义收集器。例如:

Stream<String> stream = Stream.of("apple", "banana", "cherry");
List<String> collectedList = stream.collect(Collectors.toList()); // 收集为 List

归约(Reduce):reduce() 方法用于将 Stream 中的元素依次进行二元操作,得到一个最终的结果。它接受一个初始值和一个 BinaryOperator 函数作为参数。例如:

Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
Optional<Integer> sum = stream.reduce((a, b) -> a + b); // 对所有元素求和

统计(Summary Statistics):summaryStatistics() 方法可以从 Stream 中获取一些常用的统计信息,如元素个数、最小值、最大值、总和和平均值。例如:

IntStream stream = IntStream.of(1, 2, 3, 4, 5);
IntSummaryStatistics stats = stream.summaryStatistics();
System.out.println("Count: " + stats.getCount());
System.out.println("Min: " + stats.getMin());
System.out.println("Max: " + stats.getMax());
System.out.println("Sum: " + stats.getSum());
System.out.println("Average: " + stats.getAverage());

以上只是 Stream API 提供的一部分常用操作方法,还有许多其他操作方法,如匹配(Match)、查找(Find)、遍历(ForEach)等

文章来源:https://www.cnaaa.net,转载请注明出处:https://www.cnaaa.net/archives/9621

(0)
郭靖的头像郭靖
上一篇 2023年8月31日 下午8:27
下一篇 2023年9月5日 下午5:03

相关推荐

  • 企业如何做好业务监控​?

    大部分企业都会做基础设施监控,觉得做好基础设施监控就可以解决大部分问题。至于业务方面监控,等有人来说了再处理就行。殊不知这种想法会有诸多隐患。 为什么要做业务监控? 通常情况下,大部分企业都会做基础设施监控,觉得做好基础设施监控就可以解决大部分问题。至于业务方面监控,等有人来说了再处理就行。殊不知这种想法会有诸多隐患: 1、运维比业务部门经常晚发现业务有问题…

    2023年12月6日
    65100
  • DNS BIND主辅同步配置

    DNS主辅同步配置要点: DNS主辅环境 主DNS我们已经安装过bind了,接下来在辅助DNS安装bind 具体安装详解可以查看下面的文章 接下来修改辅助DNS配置文件 接下来修改主dns配置文件 dns master完整配置文件如下 现在我们将dns01 和dns02执行下面的命令,检查配置文件是否有错误 重启主dns 接下来我们去辅助dns,检查完全区域…

    2023年3月31日
    76400
  • 华为s5735交换机配置ssh远程登陆

    (1)进入aaa模式 (2)创建用户和账户:local-user 用户名 password cipher 密码 (3)开启用户登陆方式是ssh:local-user 用户名 service-type ssh telnet (4)赋予用户权限:local-user 用户名 privilege level 级别 (5)开启stelnet服务:stelnet se…

    2023年4月10日
    1.5K00
  • 使用Dockerfile创建镜像,创建容器并运行

    一般情况下并不推荐使用“docker commit”来构建镜像,而应该使用更灵活、更强大的Dockerfile来构建Docker镜像,这里就来说一下使用Dockerfile创建镜像,创建容器并运行的方法。 1 生成镜像1.1 准备Dockerfile文件准备Dockerfile文件内容如下: 由于创建过程用到了java文件,这里要将注意这里要将java文件和…

    2023年8月10日
    74100
  • 常用华为网络设备display命令合辑,真香!

    下午好,我的网工朋友。 今天给你做了个命令整合,华为设备提供了多条display命令用于查看硬件部件、接口及软件的状态信息。 通常这些状态信息可以为用户故障处理提供定位思路。 01 常用的故障信息搜集命令 信息项 使用命令 使用说明 基本信息 display diagnostic-information 此命令主要用于系统基本信息的收集,集合了多条常用dis…

    2024年1月15日
    96300

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

在线咨询: QQ交谈

邮件:712342017@qq.com

工作时间:周一至周五,8:30-17:30,节假日休息

关注微信