6

我目前正在查看 Javaslang 库,并且正在尝试将我的一些代码转换为 Javaslang。

我目前有这段代码,都是纯Java

Cell[][] maze; //from input
Map<Cell, Long> cellCounts = Stream.of(maze)
            .flatMap(Stream::of)
            .collect(groupingBy(c -> c, counting()));

我正在考虑将其转换为 Javaslang,因为我对这个库很感兴趣,我只是想玩弄它。

我正在尝试做类似的事情,但转换为 Javaslang 映射而不是 java.util.Map。

到目前为止我已经尝试过了,但后来我被卡住了,因为我看不到转换它的方法。

Array.of(maze)
     .flatMap(Array::of)

所以我有我的 Cell 对象列表,但我想弄清楚如何将其转换为 javaslang.collection.Map

*编辑 *

我已经研究过通过这个将我原来的 java.util.Map 转换为 javaslang.collections.Hashmap

HashMap<Cell, Long> cellsCount = HashMap.ofEntries(cellCounts
                                                        .entrySet()
                                                        .toArray(new Map.Entry[0]));

这似乎仍然不符合 Javaslang,但我会继续寻找。

4

3 回答 3

4

通常 grouping by 有另一种方法,该方法采用您尝试转换的 Map 实现,但它必须是实际扩展的类型java.util.Map

Collectors.groupingBy(classifier, mapFactory, downstream)

从我看到javaslang.collection.Map的是一个接口,而不是一个实际的实现。

由于没有可以扩展的 javaslang Map 的实现java.util.Map,您所能做的就是创建一个自定义收集器。

或者一旦已经收集到java.util.Map- 将它们放入javaslang.collection.Map.

于 2017-03-01T15:23:24.193 回答
3

虽然Eugene提供的答案通常是正确的:必须有人制作自定义收集器。

然而,这不一定是你:Javaslang 人已经为你处理好了,通过提供在 Javaslang 映射的具体实现上可用的必要方法,这些方法可以在最简单的情况下工作。例如,在 Javaslang 上HashMap

javaslang.collection.HashMap::collector()

public static <K,V> Collector<Tuple2<K,V>,ArrayList<Tuple2<K,V>>,HashMap<K,V>> collector()

返回一个收集器,它可以与 Stream.collect(java.util.stream.Collector) 结合使用以获得一个 HashMap。

类型参数

K - 密钥类型

V - 值类型

返回

HashMap 收集器。

编辑: 但是,它看起来不一定会起作用,因为从收藏家的签名来看:

  1. 期待一个流Tuple<K,V>
  2. 将该流的所有元素收集到一个ArrayList<Tuple2<K,V>>
  3. 收集完所有元素后,它通过将所有内容添加ArrayListHashMap.

这显然行不通,因为您有Stream<Cell>,并且您想计算它们。然而,这个签名实际上给了我们一些东西:它指出内置的 Javaslang 收集器不会直接收集到 Javaslang Map 中(至少不是在HashMap. 知道了这一点,我们可以寻找将 Java Map 转换为 Javaslang map 的方法,我们会发现:

javaslang.collection.HashMap::ofAll(java.util.Map)

从源 java.util.Map 返回一个 HashMap。

我们可以在你所拥有的基础上添加这个方法:

Stream<Cell> cells // <- you have this

cells.collect(
  collectingAndThen(
    groupingBy(Function.identity(), counting()),
    HashMap::ofAll
  )
);

您可以在 中找到所有没有限定符的方法java.util.stream.Collectors

该片段将收集到普通 JavaMap中,最后一步将调用 Collector 的 Finisher,它将 java Map 中的所有值放入 Javaslang 映射中。

注意:我没有安装 Javaslang,无法测试上面的代码片段是否编译,但它看起来像你想要的。

于 2017-03-01T15:56:02.247 回答
2

免责声明:我是 Javaslang 的作者。

使用 Javaslang 实现它的最简单方法如下:

    Map<Cell, Integer> cellCounts = Array.of(maze)
            .flatMap(Array::of)
            .groupBy(c -> c)
            .mapValues(Array::length);

这里ArrayMap是从 导入的javaslang.collection

请注意,您可以替换Array为任何其他SeqSet实现。

于 2017-03-12T00:59:27.610 回答