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

相关推荐

  • IIS6.0安装不同版本PHP

    智创PHP8安装包下载:https://www.zcnt.com/IIsSafeWeb.asp 1、将下载的 PHP 8 安装包解压缩     2、运行 setup.exe ,然后点“下一步”开始安装     3、开始复制 php文件     4、文件复制完成后,会弹出一个 DOS界面窗口,开始检查 IIS环境和对 IIS增加 PHP 8 支持     5、…

    2023年4月14日
    32600
  • 企业如何做好业务监控​?

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

    2023年12月6日
    15800
  • Prometheus 通过 consul 实现自动服务发现

    1、Consul 安装配置 Consul 安装很方便,官网 提供各个系统版本二进制安装包,解压安装即可,同时也可以通过 Docker 来快速安装。 1.1、源码安装 以 Linux 系统为例,源码安装并以开发模式启动一个单节点,下载最新版二进制安装包,解压启动即可。 启动完毕后,浏览器访问 http://127.0.0.1:8500 地址,即可打开 Cons…

    2023年8月7日
    21300
  • 深入浅出TCP中的SYN-Cookies

    SYN Flood 攻击 TCP连接建立时,客户端通过发送SYN报文发起向处于监听状态的服务器发起连接,服务器为该连接分配一定的资源,并发送SYN+ACK报文。对服务器来说,此时该连接的状态称为半连接(Half-Open),而当其之后收到客户端回复的ACK报文后,连接才算建立完成。在这个过程中,如果服务器一直没有收到ACK报文(比如在链路中丢失了),服务器会…

    2023年7月29日
    28700
  • 小小的网络故障,带来深深的思考,运维的成败果然在于细节

    早晨8点多,收到Zabbix的邮件告警,显示客户的戴尔服务器和爱快路由器掉线了,由于该客户的机房之前有过多次停电,症状当然也是如此这般,加上客户没有电话或者微信报修,就先入为主地判定为机房又停电了,因此未采取任何措施。 直到过了下班时间,客户才反馈:外网无法使用向日葵远程控制服务器。因为不止一次,也就直说了,是不是机房又没电。 客户反馈有电,照片显示服务器处…

    2天前
    1700

发表回复

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

在线咨询: QQ交谈

邮件:712342017@qq.com

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

关注微信