【问题标题】:How can a stream be collected into a JAX-RS MultivaluedMap?如何将流收集到 JAX-RS MultivaluedMap 中?
【发布时间】:2021-01-21 15:41:20
【问题描述】:

如何将Stream 的项目收集到MultivaluedMap 中?内置的 Java Map 收集器不能很好地用于此目的,因为它们希望对映射的列表类型 (K,List<V>) 进行操作,而不是 MultivaluedMap (<K,V>) 的类型。

【问题讨论】:

  • 关于书籍、工具、软件库等的建议的问题与 Stack Overflow 无关,抱歉。 stackoverflow.com/help/on-topic
  • @ra74 — 如前所述,您的问题很容易被视为软件推荐问题。我认为除此之外这是一个非常有效的问题,并且可以很容易地转换为一个不太可能因此而关闭的问题。我冒昧地对帖子进行了相应的编辑。
  • 如果这个被重新打开,我会添加这个作为一个正确的答案。一种解决方法,但一种解决方案是将现有的收集器用于不同的多图类型(这里是 Guava 的Multimap),然后将其转换为MultivalueMap。就是这样一个收藏家:Collectors.collectingAndThen(Multimaps.toMultimap(keyFunction, valueFunction, ArrayListMultimap::create),m -> {MultivaluedHashMap<String, Integer> result = new MultivaluedHashMap<>();result.putAll(Multimaps.asMap(m));return;});
  • 如果这个被重新打开,我会添加这个作为一个正确的答案。这将使用 java.util.Stream 库完成您想要做的事情:Collector.of(MultivaluedHashMap::new,(multimap, input) -> multimap.add(keyFunction.apply(input), valueFunction.apply(input)),(multimap1, multimap2) -> {multimap1.putAll(multimap2);return multimap1;});
  • @M.Justin 此问题现已重新开放。

标签: java java-stream jax-rs


【解决方案1】:

Stream.collect(supplier, accumulator, combiner) 方法可用于完成此操作。以下将从流中创建 MultivaluedMap 和任意 keyFn & valueFn Function 对:

MultivaluedMap<K, V> multimap = list.stream().collect(
        MultivaluedHashMap::new,
        (multimap, input) -> multimap.add(keyFn.apply(input), valueFn.apply(input)),
        MultivaluedMap::putAll);

这会使用new MultivaluedHashMap() 创建一个或多个多图,使用MultivaluedMap.add() 将元素添加到这些多图,并使用MultivaluedMap.putAll() 将这些多图组合在一起。

Stream.collectJavadocs 解释了这种方法:

对此流的元素执行mutable reduction 操作。可变归约是一种归约值是可变结果容器(例如ArrayList)的归约,通过更新结果的状态而不是替换结果来合并元素。

由于可以并行处理流,因此可能会创建多个临时MultivaluedMap 实例,每个实例都包含Stream 值的子集。通过使用putAll 将临时多图合并为一个MultivaluedMap,将临时多图中的所有元素放入其中一个多图中,然后将其作为最终结果返回。

示例

以下将从Stream&lt;String&gt; 创建一个MultivaluedMap&lt;Integer, String&gt;,其中键是字符串的长度,值是字符串本身:

Stream<String> strings = Stream.of("Ant", "Ball", "Cat", "Ant", "House");
MultivaluedMap<Integer, String> stringsByLength = strings.collect(
        MultivaluedHashMap::new,
        (multimap, input) -> multimap.add(input.length(), input),
        MultivaluedMap::putAll
);
System.out.println(stringsByLength); // {3=[Ant, Cat, Ant], 4=[Ball], 5=[House]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多