java - Stream、Map、Reduce……是怎么做到的?

标签 java mapreduce java-8 java-stream

我正在尝试深入了解 Java 8 流,但时不时仍会卡住。我目前有一个问题,我知道它可以通过流来完成,但我似乎无法理解如何正确使用它们。

我有一个字符串列表 A 并尝试根据特定规则找到 A 的所有元素 a 与 A 的另一个元素 b 匹配,然后创建一个 Map<String, List<String>>所有 a -> 所有匹配的 b。

详细说明:

  • 对于 A 中的每个 a,使用谓词 P 与 A 中的每个 b 进行比较。
  • 如果 P(a,b) 匹配,则从 a 和 b 生成一对 (x, y)。
  • 按 x 对所有对分组并作为 map 返回。

你能给我一个有效的 Java 8 流示例吗?

编辑:我将如何以一种不必要的昂贵方式做到这一点:

Pairs(x,y) = forEach(a,b in A) 
  where (a != b && P(a, b)) 
  generatePairXY(a, b)
Map(x -> List(y)) = group(Pairs(x,y)) by x

这种方法的问题是我首先需要构建一个巨大的对列表,考虑到我的几百万个单词的数据集,这可能会耗尽内存。

最佳答案

List<String> list = ...;
Map<String, List<String>> map = 
  list.stream()
      .collect(Collectors.toMap(a -> a, a -> list.stream()
                                                 .filter(b -> P(a,b))
                                                 .collect(Collectors.toList()))
               );

我们的想法是创建一个映射,其中包含原始列表中每个字符串的键,以及一个匹配该键的所有字符串的过滤列表。

编辑:

这是一个完整的工作示例,其中如果两个字符串不相等但长度相同,则谓词 P 返回 true :

package com.test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class Test
{

  public static boolean P (String a, String b)
  {
    return a.length() == b.length() && !a.equals(b);
  }

  public static void main (String[] args)
  {
    List<String> list = new ArrayList<String>();
    list.add ("aaa");
    list.add ("bbb");
    list.add ("ccc");
    list.add ("cccc");
    list.add ("dddd");
    list.add ("ddd");

    Map<String, List<String>> map = 
      list.stream()
          .collect(Collectors.toMap(a -> a, a -> list.stream()
                                                     .filter(b -> P(a,b))
                                                     .collect(Collectors.toList()))
               );
    for (String key : map.keySet ()) {
      System.out.print (key + ": " );
      for (String value : map.get(key)) {
        System.out.print (value+ " ");
      }
      System.out.println("");
    }
  }

}

输出:

aaa: bbb ccc ddd
ccc: aaa bbb ddd
bbb: aaa ccc ddd
ddd: aaa bbb ccc
dddd: cccc
cccc: dddd

关于java - Stream、Map、Reduce……是怎么做到的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25105529/

相关文章:

Peek 中的 Java 8 条件逻辑?

java - 从 session 变量中删除特定变量

java - 在这种情况下是否可以实现 hashCode() 方法?

hadoop - 如何在 hadoop/map reduce 中创建具有固定行数的输出文件?

java - Hadoop : JPS can not find Java installed

java - 我应该为 netbeans 使用什么 JDK?

java - 在 Java 中,尝试写入命名管道时出现空指针异常

java - 简单的 GUI 指导。我可以坚持使用 BorderLayout 还是需要其他东西?

java - 无法使用方面拦截对方付费调用

java - 嵌套 if-object-null-return 方法提取或替代 Sonar 认知复杂性