流动使用介绍:
- 新用户可能会发现很难在流管中表达计算。
- streams 以函数编程为基础,提供表现力、速度和并行化。
计算结构:
- 使用纯函数作为转换序列进行结构计算。
- 纯函数仅依赖于它们的输入而不改变状态。
副作用:
- 避免传输给流操作的函数产生副作用。
- 不正确使用改变外部状态的方法 foreach 是一种“难闻的气味”。
示例1:代码具有副作用
map<string long> freq = new hashmap(); try (stream<string> words = new scanner(file).tokens()) { words.foreach(word -> { freq.merge(word.tolowercase(), 1l, long::sum); }); } </string></string>
问题:该代码使用foreach修改外部状态(freq)。它是迭代的,不使用流量。
示例2:代码没有副作用
map<string long> freq; try (stream<string> words = new scanner(file).tokens()) { freq = words.collect(collectors.groupingby(string::tolowercase, collectors.counting())); } </string></string>
解决方案: 使用 collectors.groupingby 在不改变外部状态的情况下,收集器创建频率表。更短、更清晰、更高效。
占用流api:
- 模仿迭代循环的代码不使用流量。
- 使用收集器进行更高效、更可读的操作。
收藏家:
- 简化将结果收集到列表和集合中。
- collectors.tolist()、collectors.toset()、collectors.tocollection(collectionfactory).
示例 3:提取十个最常见单词的列表
list<string> topten = freq.entryset().stream() .sorted(map.entry.<string long>comparingbyvalue().reversed()) .limit(10) .map(map.entry::getkey) .collect(collectors.tolist()); </string></string>
说明:
- 频率图条目按值降序排列。
- 将直播限制为 10 个字。
- 收集列表中最常见的单词。
收集器 api 的复杂性:
- api 有 39 一种方法,但很多都是高级用的。
- 收集器可用于创建地图(tomap、groupingby)。
地图及收集策略:
- tomap(keymapper, valuemapper) 获得唯一的键值。
- 按键冲突采用合并功能处理策略。
- groupingby 元素按分类器函数分组。
示例4:使用具有合并功能的tomapp
map<string long> freq; try (stream<string> words = new scanner(file).tokens()) { freq = words.collect(collectors.tomap( string::tolowercase, word -> 1l, long::sum )); } </string></string>
说明:
- tomap 将单词映射到它们的频率上。
- 合并函数(long::sum)关键冲突是通过对频率的求和来处理的。
示例 5:根据艺术家对专辑进行分组,找到最畅销的专辑
map<artist album> topalbums = albums.stream() .collect(collectors.tomap( album::getartist, function.identity(), binaryoperator.maxby(comparator.comparing(album::sales)) )); </artist>
说明:
- tomap 将艺术家映射到他们最畅销的专辑中。
- binaryoperator.maxby 确定每个艺术家最畅销的专辑。
字符串集合: collectors.joining 使用可选分隔符连接字符串。
示例 6:使用分隔符连接字符串
String result = Stream.of("came", "saw", "conquered") .collect(Collectors.joining(", ", "[", "]"));
说明:
- collectors.joining 将逗号作为连接字符串的分隔符、前缀和后缀。
- 结果:[来,看,征服].
结论:
- 流动的本质在于无副作用的函数。
- foreach 只能用于报告结果。
- 收集器的知识对有效使用流至关重要。
以上是Item 优先考虑流中无副作用函数的详细内容,请关注图灵教育的其他相关文章!