Java中stream是什么?有什么作用?如何使用?

2023-09-17 17:30:29

Java中stream是什么?有什么作用?如何使用?

在Java中,Stream(流)是一种用于操作集合(Collection)、数组等数据源的API。它提供了一种功能强大且表达力高的编程模型,可以用更简洁、更具可读性的方式处理数据。

Stream的主要作用是进行数据的转换、筛选、聚合等操作,可以极大地简化对数据的处理。使用Stream可以避免显式地使用迭代器或循环来操作集合,提高代码的可读性和简洁性。

以下是使用Stream的一般步骤:

  1. 获取一个数据源(如List、Set、数组等)。
  2. 调用stream()方法获取数据流。
  3. 使用各种中间操作对数据流进行处理(如筛选、转换等)。
  4. 调用终端操作执行对数据流的最终处理(如聚合、收集结果等)。

下面通过示例代码详细介绍Stream的使用:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        // 1. 获取数据源
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // 2. 获取数据流
        List<Integer> evenSquares = numbers.stream()
                // 3. 中间操作:筛选偶数并计算平方
                .filter(n -> n % 2 == 0)
                .map(n -> n * n)
                // 4. 终端操作:收集结果
                .collect(Collectors.toList());

        System.out.println(evenSquares); // 输出:[4, 16, 36, 64, 100]
    }
}

在上述示例中,我们首先获取了一个整数列表作为数据源。然后,通过调用stream()方法获取了一个数据流。接着,使用中间操作filter()筛选出偶数,再使用map()计算平方。最后,通过终端操作collect()将结果收集到列表中。

这只是Stream的基本用法,Stream还提供了丰富的中间操作和终端操作供使用,如sorted()distinct()reduce()等。通过组合不同的操作,可以实现复杂的数据处理逻辑。

stream用法:

  1. filter(Predicate<T> predicate):根据指定的条件筛选元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
// 输出:[2, 4]

  1. map(Function<T, R> mapper):将元素转换为另一种类型。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<String> result = list.stream().map(n -> "Number: " + n).collect(Collectors.toList());
// 输出:["Number: 1", "Number: 2", "Number: 3", "Number: 4", "Number: 5"]

  1. flatMap(Function<T, Stream<R>> mapper):将流中的每个元素转换为一个流,然后将所有流合并为一个流。
List<List<Integer>> lists = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4, 5));
List<Integer> result = lists.stream().flatMap(list -> list.stream()).collect(Collectors.toList());
// 输出:[1, 2, 3, 4, 5]

  1. distinct():去除流中重复的元素。
List<Integer> list = Arrays.asList(1, 2, 3, 2, 4, 1, 5);
List<Integer> result = list.stream().distinct().collect(Collectors.toList());
// 输出:[1, 2, 3, 4, 5]

  1. sorted():对流中元素进行排序。
List<Integer> list = Arrays.asList(5, 3, 1, 2, 4);
List<Integer> result = list.stream().sorted().collect(Collectors.toList());
// 输出:[1, 2, 3, 4, 5]

  1. peek(Consumer<T> action):对流中的元素执行指定的操作。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().peek(n -> System.out.println("Processing element: " + n)).collect(Collectors.toList());
// 输出:Processing element: 1 Processing element: 2 Processing element: 3 Processing element: 4 Processing element: 5

  1. limit(long maxSize):截取流中的前N个元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().limit(3).collect(Collectors.toList());
// 输出:[1, 2, 3]

  1. skip(long n):跳过流中的前N个元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().skip(3).collect(Collectors.toList());
// 输出:[4, 5]

  1. forEach(Consumer<T> action):对流中的每个元素执行指定的操作。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
list.stream().forEach(n -> System.out.println(n));
// 输出:1 2 3 4 5

  1. collect(Collector<T, A, R> collector):将流中的元素收集到一个容器中。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> result = list.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
// 输出:[2, 4]

  1. count():返回流中的元素个数。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
long count = list.stream().count();
// 输出:5

  1. reduce(T identity, BinaryOperator<T> accumulator):将流中的元素逐个与初始值进行操作,返回最终结果。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().reduce(0, (a, b) -> a + b);
// 输出:15

  1. findFirst()findAny():返回流中的第一个元素或任意一个元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> first = list.stream().findFirst();
Optional<Integer> any = list.stream().findAny();
// 输出:1

  1. max()min():返回流中的最大元素或最小元素。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> max = list.stream().max(Integer::compareTo);
Optional<Integer> min = list.stream().min(Integer::compareTo);
// 输出:5 1

  1. allMatch(Predicate<T> predicate)anyMatch(Predicate<T> predicate)noneMatch(Predicate<T> predicate):分别返回流中所有元素是否满足指定条件、是否至少有一个元素满足指定条件、是否没有元素满足指定条件。
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
boolean allMatch = list.stream().allMatch(n -> n > 0);
boolean anyMatch = list.stream().anyMatch(n -> n % 2 == 0);
boolean noneMatch = list.stream().noneMatch(n -> n > 5);
// 输出:true true false

Stream是Java 8引入的一组 API,它提供了一种新的并行处理集合数据的方式,可以让开发者更加方便、高效地对集合进行操作。

Stream 是基于管道(Pipe)和过滤器(Filter)的模式,通过对数据源执行一系列中间操作(Intermediate Operations)和终端操作(Terminal Operations)来完成对数据的处理。

利用 Stream API,我们可以在不改变原有数据结构的前提下,方便地进行数据的筛选、排序、映射、聚合等操作,并且这些操作可以串行或并行地执行,以提高计算效率。

Stream流用途:

简化集合操作:Stream提供了丰富的中间操作和终端操作,可以更简洁地对集合进行筛选、转换、排序等操作,避免了使用传统的for循环等繁琐的操作。

并行处理:Stream API天然支持并行处理,可以自动将集合数据分成多个部分并行处理,提高处理的效率。

减少内存消耗:Stream API采用惰性求值的方式,在处理大量数据时可以只在需要时才进行计算,避免了一次性加载所有数据到内存中。

代码简洁、可读性好:Stream的链式调用和函数式编程风格使代码更加简洁、易读。每个操作都可以看作是对数据流的一次转换或处理,使得代码更加直观。

支持无限大的数据集:Stream API对于无限大的数据集也能处理,并且可以利用短路特性进行优化。

与Lambda表达式结合:Stream API广泛使用Lambda表达式,可以简化代码,提高开发效率。

更多推荐

案例实践丨基于SkyWalking全链路监控的微服务系统性能调优实践篇

1背景随着开源社区和云计算的快速推进,云原生微服务作为新型应用系统的核心架构,得到了越来越广泛的应用。根据Gartner对微服务的定义:“微服务是范围狭窄、封装紧密、松散耦合、可独立部署且可独立伸缩的应用程序组件。”微服务之父,马丁.福勒,对微服务概述如下:就目前而言,对于微服务业界并没有一个统一的、标准的定义。但通常

Unity 开发人员转CGE(castle Game engine)城堡游戏引擎指导手册

Unity开发人员的城堡游戏引擎概述一、简介2.Unity相当于什么GameObject?3.如何设计一个由多种资产、生物等组成的关卡?4.在哪里放置特定角色的代码(例如生物、物品)?Unity中“向GameObject添加MonoBehaviour”相当于什么?5.Unity子目录相当于什么Assets?6.支持哪些

git基本使用

一、Git简介Git是一个免费的、开源的分布式版本控制系统,可以快速高效地处理从小型到大型的各种项目。Git易于学习,占地面积小,性能极快。它具有廉价的本地库,方便的暂存区域和多个工作流分支等特性。其性能优于Subversion、CVS、Perforce和ClearCase等版本控制工具。1.版本控制的三个阶段版本控制

深度解析Java虚拟机(JVM)的垃圾回收机制

AI绘画关于SD,MJ,GPT,SDXL百科全书面试题分享点我直达2023Python面试题2023最新面试合集链接2023大厂面试题PDF面试题PDF版本java、python面试题项目实战:AI文本OCR识别最佳实践AIGamma一键生成PPT工具直达链接玩转cloudStudio在线编码神器玩转GPUAI绘画、A

浅谈大数据背景下用户侧用电数据在电力系统的应用与发展分析

安科瑞华楠摘要:随着能源互联网、互联网+、新型传感技术的持续推进,电力用户侧用电数据呈现指数级剧增、异构性增强的情况,逐渐构成了用户侧用电行为大数据。然而目前对电力领域的数据价值挖掘于电网内部和电源端,用户侧庞大且蕴含丰富价值的电力数据而未能得到很好利用。文章主要是在用户侧用电行为大数据的基础上,对用户侧电力数据价值在

机器学习(16)---聚类(KMeans)

聚类一、聚类概述1.1无监督学习与聚类算法1.2sklearn中的聚类算法二、KMeans2.1基本原理2.2簇内误差平方和三、sklearn中的KMeans3.1所用模块3.2聚类算法的模型评估指标3.3轮廓系数3.4CHI(卡林斯基-哈拉巴斯指数)四、KMeans做矢量量化4.1概述4.2案例一、聚类概述1.1无监

负载均衡算法介绍及应用连接池负载不均问题分析

在分布式系统架构下,为了满足高并发和高扩展性的要求,负载均衡设备得以广泛的使用。结合应用连接池的配置,在实际使用过程中可能会出现负载不均的问题。本文简单介绍了负载均衡算法、Druid连接池配置以及连接池负载不均的问题分析及优化方法。1、负载均衡基本概念1.1负载均衡介绍在分布式架构下随着逻辑业务的快速发展,系统架构也随

元宇宙安全与著作权相关市场与技术动态:韩国视角

元宇宙市场动态元宇宙安全与著作权维护技术现状元宇宙有可能为商业创造巨大价值,尤其是在零售和时尚领域。时尚产品的象征性价值不仅在物理空间中得以保持,在虚拟空间中也是如此。通过元宇宙平台,企业可以开发虚拟产品,降低供应链和库存管理的风险。随着虚拟化和触觉技术的发展,消费者可以通过体验产品的物理特性做出更好的购买决策。通过将

go 1.18新特性(泛性 模糊测试 WorkSpace)

文章目录泛型interface的功能扩展泛型使用模糊测试模糊测试的使用模糊测试的缺点GoWorkSpace泛型interface的功能扩展在1.18之前,官方对interface的定义是方法的集合,可以存储实现该方法的任意类型。1.18对interface的定义改为类型集合。接口类型的变量可以存储这个接口类型集合的任意

go-channel

设计原理Go提及的设计模式就是:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。共享内存方式:多个协程共享同一块内存,但是多个协程中读写变量是操作同一块内存,会产生多线程问题的并发问题,所以需要使用互斥锁来实现临界区的互斥访问,会大大影响效率通信方式(go语言使用):channel通道当做通信的中间件队

Go底层总结

Go专家编程常见数据结构实现原理channelchannel主要用于进程内各goroutine间通信,如果需要跨进程通信,建议使用分布式系统的方法来解决向channel写数据如果等待接收队列recvq不为空,说明缓冲区中没有数据或者没有缓冲区,此时直接从recvq取出G,并把数据写入,最后把该G唤醒,结束发送过程;如果

热文推荐