代码之家  ›  专栏  ›  技术社区  ›  Bikas Katwal

Java 8流,将对象列表转换为映射<string,设置<String >

  •  3
  • Bikas Katwal  · 技术社区  · 6 年前

    我已经举出了几个例子,但这些都不适合我。

    我想做的是:

    我有一个 List<SomeClass> 属于以下类别:

    class SomeClass {
      String rid;
      String name;
      ...
    }
    

    我的价值观 List 如下所示:

    SomeClass(1,"apple")
    SomeClass(1,"banana")
    SomeClass(1,"orange")
    SomeClass(2,"papaya")
    SomeClass(2,"peaches")
    SomeClass(3,"melons")
    

    我想转换上面的内容 变成一个 Map<String, Set<String>> ,键在哪里 rid 价值是 Set 属于 name 字段。

    用Java解决这个问题 Streams 我正在使用 groupingBy 我可以得出以下解决方案:

    someClassList
                .stream()
                .map(SomeClass::getName)
                .collect(
                      Collectors.groupingBy(
                          SomeClass::getRid, Collectors.toSet()));
    

    但这给了我编译错误。 我如何解决这个问题?我的方法有什么问题?

    2 回复  |  直到 6 年前
        1
  •  6
  •   Eran    6 年前

    当你打电话的时候 .map(SomeClass::getName) 在您的 Stream<SomeClass> ,你得到一个 Stream<String> . 你不能执行 collect(Collectors.groupingBy(SomeClass::getRid,...)) 在一 流<字符串> (您只能在 流<someClass> ) 因此你的 map 步骤错误。

    你需要通过 Collector 返回者 Collectors.mapping() Collectors.groupingBy() 为了绘制 SomeClass 实例到 String S 之后 它们按 getRid .

    Map<String, Set<String>> map =
        someClassList.stream()
                     .collect(Collectors.groupingBy(SomeClass::getRid, 
                                                    Collectors.mapping(SomeClass::getName,
                                                                       Collectors.toSet())));
    
        2
  •  2
  •   Ousmane D.    6 年前

    虽然不像 groupingBy 收集器;您可以使用 toMap 收藏家也一样:

    myList.stream()
          .collect(toMap(SomeClass::getRid, e -> new HashSet<>(singleton(e.getName())), 
                     (l, r) -> {l.addAll(r); return l;}));
    

    确保您有必要的进口 singleton 托马斯 或者你可以只用 Collectors.toMap(...) Collections.singleton(...) 分别。