May 2025
Intermediate to advanced
424 pages
6h 12m
Chinese
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
Java 和 Kotlin 都允许我们对集合进行转换和还原。 不过它们的设计目标和实现方式各不相同。 Kotlin 用什么来代替 Java 流,我们应该在什么时候转换,以及如何转换?
Java 8 在 2014 年引入了流,很好地利用了新的 Lambda。 假设我们想计算出一些字符串的平均长度,只是空白字符串(只有空白字符的字符串)应被当作空字符串来处理。 以前我们可能会这样写:
publicstaticdoubleaverageNonBlankLength(List<String>strings){varsum=0;for(vars:strings){if(!s.isBlank())sum+=s.length();}returnsum/(double)strings.size();}
有了 Java 流,我们可以通过先将List 转换为Stream 并应用变换,将此算法表达为filter,map, 和reduce :
publicstaticdoubleaverageNonBlankLength(List<String>strings){returnstrings.stream().filter(s->!s.isBlank()).mapToInt(String::length).sum()/(double)strings.size();}
我们不必在脑海中运行 for 循环来查看这段代码在做什么,而是可以看到逐行声明的算法步骤,并依靠运行时为我们实现这些步骤。
如果我们真的急于得到这些结果,我们甚至可以写作:
publicstaticdoubleaverageNonBlankLength(List<String>strings){returnstrings.parallelStream().filter(s->!s.isBlank()).mapToInt(String::length).sum()/(double)strings.size();}
这里有不同类型的基本操作:map 更改项的类型,而不是它们的数量;filter 根据某些属性保留或拒绝项,但保持它们的类型不变;sum 是将集合还原为单一属性。本例中未显示的操作是skip(n) 和limit(n) 。这些操作分别返回不含第一个和最后一个n 元素的数据流。
Java 流是懒惰的:strings.filter(...).mapToInt(...) 除了为某些终端操作(本例中为sum )设置管道以吸入值外,什么也不做。懒惰意味着后面的管道阶段可以限制前面阶段必须执行的工作量。 考虑翻译单词列表,直到我们看到单词STOP 。循环版本可能是这样的: ...
Read now
Unlock full access