当前位置: 首页 > 图灵资讯 > 技术篇> Item 优先选择流中没有副作用的函数

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

来源:图灵教育
时间:2024-08-14 11:31:11

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

流动使用介绍:

  • 新用户可能会发现很难在流管中表达计算。
  • streams 以函数编程为基础,提供表现力、速度和并行化。

计算结构:

  • 使用纯函数作为转换序列进行结构计算。
  • 纯函数仅依赖于它们的输入而不改变状态。

副作用:

  • 避免传输给流操作的函数产生副作用。
  • 不正确使用改变外部状态的方法 foreach 是一种“难闻的气味”。

示例1:代码具有副作用

map<string long> freq = new hashmap();
try (stream<string> words = new scanner(file).tokens()) {
    words.foreach(word -&gt; {
        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 -&gt; 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 优先考虑流中无副作用函数的详细内容,请关注图灵教育的其他相关文章!