首页 > Java > java教程 > 正文

Item 优先选择流中没有副作用的函数

WBOY
发布: 2024-08-08 16:46:52
原创
662 人浏览过

Item  Dê preferência às funções sem efeitos colaterais nas 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);
    });
}

登录后复制

问题:此代码使用 forEach 来修改外部状态(freq)。它是迭代的并且不利用流。

示例 2:无副作用的代码

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
}

登录后复制

解决方案: 使用 Collectors.groupingBy 收集器创建频率表而不更改外部状态。更短、更清晰、更高效。

占用流 API:

  • 模仿迭代循环的代码不利用流。
  • 使用收集器进行更高效和可读的操作。

收藏家:

  • 简化将结果收集到列表和集合等集合中。
  • Collectors.toList()、Collectors.toSet()、Collectors.toCollection(collectionFactory)。

示例 3:提取最常见的 10 个单词的列表

List<String> topTen = freq.entrySet().stream()
    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
    .limit(10)
    .map(Map.Entry::getKey)
    .collect(Collectors.toList());

登录后复制

说明:

  • 按值的降序排列频率映射条目。
  • 将流限制为 10 个单词。
  • 收集列表中最常见的单词。

收集器 API 的复杂性:

  • API 有 39 个方法,但很多都是供高级使用的。
  • 收集器可用于创建映射(toMap、groupingBy)。

地图和收集策略:

  • toMap(keyMapper, valueMapper) 获取唯一键值。
  • 使用合并功能处理键冲突的策略。
  • groupingBy 根据分类器函数将元素分组。

示例 4:使用带有合并功能的 toMap

Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
    freq = words.collect(Collectors.toMap(
        String::toLowerCase, 
        word -> 1L, 
        Long::sum
    ));
}

登录后复制

说明:

  • toMap 将单词映射到它们的频率。
  • 合并函数(Long::sum)通过对频率求和来处理关键冲突。

示例 5:按艺术家对专辑进行分组并查找最畅销的专辑

Map<Artist, Album> topAlbums = albums.stream()
    .collect(Collectors.toMap(
        Album::getArtist,
        Function.identity(),
        BinaryOperator.maxBy(Comparator.comparing(Album::sales))
    ));

登录后复制

说明:

  • toMap 将艺术家映射到他们最畅销的专辑。
  • BinaryOperator.maxBy 确定每位艺术家的最畅销专辑。

字符串集合:
Collectors.joining 将字符串与可选分隔符连接起来。

示例 6:使用分隔符连接字符串

String result = Stream.of("came", "saw", "conquered")
    .collect(Collectors.joining(", ", "[", "]"));

登录后复制

说明:

  • Collectors.joining 使用逗号作为分隔符、前缀和后缀连接字符串。
  • 结果:[来、看到、征服]。

结论:

  • 流的本质在于没有副作用的函数。
  • forEach 只能用于报告结果。
  • 有关收集器的知识对于有效使用流至关重要。

以上是Item 优先选择流中没有副作用的函数的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!