Java流API的综合指南
Java Stream API提供了一种声明的功能方法来处理数据序列而无需修改源。 2。流是根据集合,数组或使用stream.of()的()来创建流的,并通过iTerate()或generate()支持无限流。 3。诸如过滤器,地图和排序之类的中间操作是懒惰的,并返回新流,而终端操作(例如foreach,collect和计数触发器执行)。 4。collect()方法使用内置的收集器(例如Tolist,GroupingBy和partitioningby)收集收集或摘要。 5。扁平图平坦的嵌套结构,例如list >到一个流中。 6。诸如FindFirst Report的操作可选,以安全处理不存在值的操作。 7。通过ParalleStream()平行流对大数据集进行并发处理,但需要谨慎对共享状态和开销进行谨慎。 8。最佳实践包括避免副作用,不重复使用流以及仅在简单循环中有益时使用流。 9。应避免进行批判性能循环,索引访问或过于复杂的逻辑的流。 10。流动API促进了现代Java开发中的更清洁,更可维护的代码,用于过滤,转换和聚合。
Java 8中引入的Java流API彻底改变了开发人员如何处理数据的收集。它为Java带来了功能性编程样式,可以进行简洁,可读且通常更有效的数据处理。如果您曾经写过循环以过滤,转换或从列表中汇总数据,则流API可以使您的代码清洁器且容易出错。

让我们以实用,全面的方式分解流API - 从基础到高级用法。
什么是流?
流不是数据结构。它不存储元素。取而代之的是,它是支持功能性操作(例如map
, filter
和reduce
)的源(例如集合,数组或I/O通道)的一系列元素。

关键特征:
- 不会修改原始数据源- 操作是无损的。
- 支持懒惰评估- 中间操作直到调用终端操作后才执行。
- 可以并行处理- 最小的代码更改。
List <String> names = arrays.aslist(“ Alice”,“ Bob”,“ Charlie”); names.stream() .filter(名称 - > name.startswith(“ a”)) .map(字符串:: touppercase) .foreach(system.out :: println); //输出:爱丽丝
创建流
您可以通过几种方式创建流:

从收藏
list <string> list = arrays.aslist(“ a”,“ b”,“ c”); 流<String> stream = list.stream();
来自数组
string [] array = {“ a”,“ b”,“ c”}; 流<String>流= arrays.stream(array);
使用stream.of()
流<String>流= stream.of(“ A”,“ B”,“ C”);
无限流
使用Stream.iterate()
或Stream.generate()
进行无限序列。
流<Integer> infinite = stream.iterate(0,n-> n 2); // 0、2、4、6 ... 流<double> randoms = stream.generate(Math :: Random);
⚠️小心 - 无限流需要限制处理的终端操作(例如,
limit()
)。
中级与终端操作
流使用操作管道:
- 中间操作返回新流(它们很懒惰)。
- 终端操作触发实际处理并返回结果或副作用。
常见的中间操作
filter(Predicate<T>)
:保持与条件匹配的元素。-
map(Function<T,R>)
:转换每个元素。 -
flatMap(Function<T, Stream<R>>
)`:扁平的嵌套结构。 -
distinct()
:删除重复项。 -
sorted()
:排序元素。 -
limit(n)
:采用第一个n
元素。 -
skip(n)
:跳过第一n
元素。
例子:
列表<string>结果= word.stream() .filter(w-> w.length()> 3) .map(字符串:: touppercase) .sorted() 限制(10) .Collect(collectors.tolist());
常见的终端操作
forEach(Consumer<T>)
:对每个元素执行操作。-
collect(Collector)
:将结果收集到列表,设置,映射等。 -
count()
:元素返回数量。 -
findFirst()
:返回第一个元素(作为Optional
)。 -
anyMatch()
,allMatch()
,noneMatch()
:检查条件。 -
reduce()
:将元素组合成单个值。
收集结果collect()
collect()
方法是最强大的终端操作之一。它用于将流元素累积到集合或摘要中。
Collectors
的共同收藏家:
集电极 | 目的 |
---|---|
toList() | 收集List |
toSet() | 收集要Set |
joining() | 串联弦 |
groupingBy() | 分类器组 |
partitioningBy() | 分为true/false组 |
summingInt() , averagingDouble() | 聚合 |
mapping() | 在收集期间应用功能 |
示例:
//与逗号一起加入名称 字符串名称= people.stream() .map(person :: getName) .Collect(collectors.joining(“,”)); //按年龄分组 地图<整数,列表<人物>> byage = people.stream() 。 //分区成人与未成年人 地图<boolean,list <人物>>成人= People.Stream() 。
用flatMap
扁平的溪流
当您具有嵌套结构(例如, List<List<String>>
)时, flatMap
有助于使它们扁平。
列表<List <字符串>> ListOflists = arrays.aslist(ASLIST( Arrays.Aslist(“ A”,“ B”), Arrays.Aslist(“ C”,“ D”) ); List <string> flat = listOflists.stream() .flatmap(list :: stream) .Collect(collectors.tolist()); // [“ A”,“ B”,“ C”,“ D”]
另一个常见用途:从对象中提取值。
List <string> alltags = posts.stream() .flatmap(post-> post.getTags()。stream()) 。清楚的() .Collect(collectors.tolist());
处理可选结果
一些终端操作返回Optional<T>
以避免null
问题。
可选<string> first = word.stream() .filter(w-> w.startswith(“ q”)) .findfirst(); 如果(first.ispresent()){ system.out.println(first.get()); } //或更好: first.ifpresent(system.out :: println);
常见方法:
-
isPresent()
-
ifPresent(Consumer)
-
orElse(T)
-
orElseGet(Supplier)
-
orElseThrow()
平行流
可以使用parallelStream()
或.parallel()
并行处理流。
int sum = numbers.parallelStream() .maptoint(integer :: intvalue) 。和();
何时使用:
- 大数据集
- CPU密集型操作
- 独立元素(无共享状态)
⚠️警告:
- 并非总是更快的 - 小型数据的开销很重要。
- 避免共享可变状态(例如,更新内部的
forEach
列表)。 - 除非您使用
forEachOrdered()
否则不得保留订单。
最佳实践和陷阱
以下是一些现实世界的提示:
- ✅更喜欢流而不是循环进行过滤,映射,还原。
- ✅使lambda表达式保持简单- 提取到复杂的方法。
- ✅使用懒惰评估来获得优势- 中间操作直到终端OP才能运行。
- ❌不要重复使用流- 它们是一次性。如果需要,创建一个新的。
- ❌避免在流操作中副作用(例如,修改外部变量)。
- ❌在不测量性能的情况下不要过度使用并行流。
副作用的示例要避免:
List <string>结果= new ArrayList <>(); words.stream() .filter(w-> w.length()> 3) .foreach(结果:: add); //不良:foreach的副作用
反而:
列表<string>结果= word.stream() .filter(w-> w.length()> 3) .Collect(collectors.tolist()); // 好的
当不使用流
虽然强大,但流并不总是最好的选择:
- 简单的循环(例如,仅打印所有元素)。
- 关键性的紧身循环(流有开销)。
- 复杂的逻辑在管道中变得不可读。
- 当您需要索引访问时(流不直接曝光索引)。
对于索引访问,请考虑:
intstream.range(0,list.size()) .foreach(i-> system.out.println(i“:” list.get(i)))
概括
Java流API为您提供了一种使用数据序列的声明性方法。它可以促进不变性,合并性和清洁代码,尤其是在处理过滤,转换和聚合时。
关键要点:
- 流是懒惰的,不融合的,并且可以综合。
- 使用中间操作来构建管道。
- 最后以终端操作触发执行。
- 利用收集
collect()
进行灵活的结果收集。 - 明智地使用
parallelStream()
。 - 避免副作用和共享状态。
使用良好,流API使您的代码更具表现力和较少的错误。这是现代Java开发的核心部分。
基本上,如果您仍在编写用于过滤或映射的手动循环,则该尝试流。
以上是Java流API的综合指南的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undress AI Tool
免费脱衣服图片

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

settings.json文件位于用户级或工作区级路径,用于自定义VSCode设置。1.用户级路径:Windows为C:\Users\\AppData\Roaming\Code\User\settings.json,macOS为/Users//Library/ApplicationSupport/Code/User/settings.json,Linux为/home//.config/Code/User/settings.json;2.工作区级路径:项目根目录下的.vscode/settings

使用datetime.strptime()可将日期字符串转换为datetime对象,1.基本用法:通过"%Y-%m-%d"解析"2023-10-05"为datetime对象;2.支持多种格式如"%m/%d/%Y"解析美式日期、"%d/%m/%Y"解析英式日期、"%b%d,%Y%I:%M%p"解析带AM/PM的时间;3.可用dateutil.parser.parse()自动推断未知格式;4.使用.d

Python是实现ETL流程的高效工具,1.数据抽取:通过pandas、sqlalchemy、requests等库可从数据库、API、文件等来源提取数据;2.数据转换:使用pandas进行清洗、类型转换、关联、聚合等操作,确保数据质量并优化性能;3.数据加载:利用pandas的to_sql方法或云平台SDK将数据写入目标系统,注意写入方式与批次处理;4.工具推荐:Airflow、Dagster、Prefect用于流程调度与管理,结合日志报警与虚拟环境提升稳定性与可维护性。

是的,一个常见的CSS下拉菜单可以通过纯HTML和CSS实现,无需JavaScript。1.使用嵌套的ul和li构建菜单结构;2.通过:hover伪类控制下拉内容的显示与隐藏;3.父级li设置position:relative,子菜单使用position:absolute进行定位;4.子菜单默认display:none,悬停时变为display:block;5.可通过嵌套实现多级下拉,结合transition添加淡入动画,配合媒体查询适配移动端,整个方案简洁且无需JavaScript支持,适合大

itertools.combinations用于生成从可迭代对象中选取指定数量元素的所有不重复组合(顺序无关),其用法包括:1.从列表中选2个元素组合,如('A','B')、('A','C')等,避免重复顺序;2.对字符串取3个字符组合,如"abc"、"abd",适用于子序列生成;3.求两数之和等于目标值的组合,如1 5=6,简化双重循环逻辑;组合与排列的区别在于顺序是否重要,combinations视AB与BA为相同,而permutations视为不同;

Go中的HTTP日志中间件可记录请求方法、路径、客户端IP和耗时,1.使用http.HandlerFunc包装处理器,2.在调用next.ServeHTTP前后记录开始时间和结束时间,3.通过r.RemoteAddr和X-Forwarded-For头获取真实客户端IP,4.利用log.Printf输出请求日志,5.将中间件应用于ServeMux实现全局日志记录,完整示例代码已验证可运行,适用于中小型项目起步,扩展建议包括捕获状态码、支持JSON日志和请求ID追踪。

First,checkiftheFnkeysettingisinterferingbytryingboththevolumekeyaloneandFn volumekey,thentoggleFnLockwithFn Escifavailable.2.EnterBIOS/UEFIduringbootandenablefunctionkeysordisableHotkeyModetoensurevolumekeysarerecognized.3.Updateorreinstallaudiodriv

fixture是用于为测试提供预设环境或数据的函数,1.使用@pytest.fixture装饰器定义fixture;2.在测试函数中以参数形式注入fixture;3.yield之前执行setup,之后执行teardown;4.通过scope参数控制作用域,如function、module等;5.将共用fixture放在conftest.py中实现跨文件共享,从而提升测试的可维护性和复用性。
