【问题标题】:Stream API Java 8 Parallel Processing流 API Java 8 并行处理
【发布时间】:2018-05-16 05:54:42
【问题描述】:

我有两套

phraseSet 包含“埃菲尔铁塔”、“东京铁塔”

wordSet 包含诸如“埃菲尔”、“塔”之类的词

如何使用 Java 8 并行流来处理如下逻辑: 1. 对于phraseSet 中的每个项目,对其进行标记,查看wordSet 中是否存在所有标记,如果存在,则将该项目添加到名为resultSet 的新集合中。 在此示例中,resultSet 将包含“埃菲尔铁塔”

如果我使用传统的 for 循环很容易做到,但在尝试使用并行流时我很困惑,我希望它也更快,因为它是并行处理的。

【问题讨论】:

  • 并行处理并不总是意味着更快。
  • 在这种情况下应该更快吧,只是好奇在哪种情况下它更慢?
  • 创建并行处理和合并结果会产生开销。只有当输入集足够大(数千,如果不是数百万)和/或每个单个元素处理需要足够长的时间(秒,如果不是几分钟)时,您才会开始看到性能优势。

标签: parallel-processing java-8 java-stream


【解决方案1】:

filterallMatch 就足够了:

Set<String> phrases = new HashSet<>(Arrays.asList("eifel tower", "tokyo tower"));
Set<String> words = new HashSet<>(Arrays.asList("eifel", "tower"));
Pattern delimiter = Pattern.compile("\\s+");

Set<String> resultSet = phrases.parallelStream().filter(
    phrase -> delimiter.splitAsStream(phrase).allMatch(words::contains)
).collect(Collectors.toSet());

【讨论】:

  • 很好的答案,但我会将Pattern.compile("\\s+") 步骤移出流,以避免对每个元素重复它。另请注意,Set.of 是 Java 9,OP 可能不知道。
  • @Holger 感谢您的反馈。现在包括改进。
【解决方案2】:

最简单的解决方案是

Set<String> resultSet = phraseSet.stream()
    .filter(s -> wordSet.containsAll(Arrays.asList(s.split("\\s+"))))
    .collect(Collectors.toSet());

您可以通过将stream() 替换为parallelStream() 将其转换为并行处理,但您需要相当大的输入集才能从并行处理中受益。

请注意,如果您有很多不匹配的短语,这个简单的解决方案可能会做不必要的工作,因为它会在检查它们是否包含在wordSet 中之前创建所有子字符串。像Flown’s 这样的解决方案将推迟子字符串的创建,因此当遇到wordSet 中不包含的单词时可以跳过它(也称为短路)。另一个性能改进是将Pattern 的创建移出流处理并重新使用它(Pattern 在使用类似String.split 的方法时也会在后台创建,如上述解决方案)。

Pattern whiteSpace = Pattern.compile("\\s+");
Predicate<String> inWordSet = wordSet::contains;
Set<String> resultSet = phraseSet.stream()
    .filter(phrase -> whiteSpace.splitAsStream(phrase).allMatch(inWordSet))
    .collect(Collectors.toSet());

【讨论】:

    【解决方案3】:

    您可以在这里使用equalscontainsAll 方法。

    Set<String> resultSet = phraseSet.stream()
               .filter(s->wordSet.equals(Stream.of(s.split("\\s"))//wordSet.containsAll(...)
                      .collect(Collectors.toSet())))
               .collect(Collectors.toSet());
    

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 2017-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 2018-04-29
      • 1970-01-01
      • 2016-02-28
      相关资源
      最近更新 更多