【问题标题】:Collect into Guava's ListMultiMap using Java 8 streams使用 Java 8 流收集到 Guava 的 ListMultiMap
【发布时间】:2017-07-03 03:05:32
【问题描述】:

我正在尝试使用 java 8 在不使用 forEach 操作的情况下收集到 ListMultiMap。

如果我用 Java 7 编写代码,它会是这样的:

ListMultimap<String, String> result = ArrayListMultimap.create();
     for(State state: states) {
      for(City city: state.getCities()) {
        result.put(state.getName(), city.getName());
      }
    }

我在网上找到了一个website,它谈到了创建自己的收集器以在诸如此类的场景中使用。 我将此实现用于收集器。然后我写了以下代码:

     ListMultimap<String, String> result = states
        .stream()
        .flatMap(state -> state.getCities().stream()
            .map(city -> {
              return new Pair(state, city);
            }))
        .map(pair -> {
          return new Pair(pair.first().getName(), pair.second().getName()));
        })
        .collect(MultiMapCollectors.listMultimap(
                    Pair::first,
                    Pair::second
                )
        );

但是在collect级别,我只能传递一个参数,我似乎可以找到一种方法来传递两个参数。 按照网站上的示例,我了解到要同时使用两者,我需要在多图中存储一个“对”,如下所示:

ArrayListMultimap<String, Pair> testMap = testObjectList.stream().collect(MultiMapCollectors.listMultimap((Pair p) -> p.first().getName()));

但这不是我想要的,我想使用 Java 8 的收集器(而不是 forEach)使用州名和城市名收集到 ListMultimap。

有人可以帮我吗? 谢谢!

【问题讨论】:

  • 该链接后面的代码看起来不太好听;累加器的原始类型、未经检查的强制转换和不需要的类型变量。
  • 你是对的!感谢您指出这一点!我认为这很合理,因为我发现很多其他网站都有类似的实现。谢谢!

标签: java java-8 java-stream guava collectors


【解决方案1】:

ImmutableListMultimap.flatteningToImmutableListMultimap

return states.stream()
   .collect(flatteningToImmutableListMultimap(
      State::getName,
      state -> state.getCities().stream().map(City::getName)));

【讨论】:

    【解决方案2】:

    可以为此创建一个自定义收集器(请注意,Louis Wasserman 的答案将在内部执行 forEachOrdered,您无法真正在内部或外部逃避 forEach)。

     ListMultimap<String, String> list = states.collect(Collector.of(ArrayListMultimap::create, (multimap, s) -> {
            multimap.putAll(s.getName(), s.getCities().stream().map(City::getName).collect(Collectors.toList()));
        }, (multi1, multi2) -> {
            multi1.putAll(multi2);
            return multi1;
        })); 
    

    【讨论】:

    • 谢谢!我一直在寻找类似于 Louis Wasserman 的答案的东西,但你给了我一个很好的想法,我需要通过说“你可以创建一个自定义收集器”来做其他事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 1970-01-01
    相关资源
    最近更新 更多