使用每种类型的计数将数组转换为Javaslang Map

时间:2017-03-01 15:09:08

标签: java java-8 vavr

我目前正在查看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不符,但我会继续寻找。

3 个答案:

答案 0 :(得分:4)

通常分组依旧是另一种方法,它采用您尝试转换为的Map实现,但它必须是实际扩展java.util.Map的类型:

Collectors.groupingBy(classifier, mapFactory, downstream)

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

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

或者已经收集到java.util.Map - 将这些内容放入javaslang.collection.Map的某个实例中。

答案 1 :(得分:3)

虽然提供的answer that Eugene通常是正确的:某人必须制作自定义收藏家。

然而,这并不一定是你:Javaslang人已经为你照顾它,通过提供Javaslang地图的具体实现可用的必要方法,这些方法将在最简单的情况下工作。例如,在Javaslang上HashMap

  

javaslang.collection.HashMap::collector()

     

public static&lt; K,V&gt;集电极&LT; Tuple2&LT; K,V&GT;,&ArrayList的LT; Tuple2&LT; K,V&GT;&GT;,&HashMap的LT; K,V&GT;&GT;集电极()

     

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

     

类型参数

     

K - 密钥类型

     

V - 值类型

     

<强>返回

     

HashMap收集器。

修改 但是,它看起来并不一定有效,因为根据收藏家的签名判断:

  1. 预计会有Tuple<K,V>
  2. 的信息流
  3. 将该流的所有元素收集到ArrayList<Tuple2<K,V>>
  4. 收集完所有元素后,它就会完成&#34;将ArrayList的所有内容添加到HashMap
  5. 这显然不起作用,因为你有Stream<Cell>,并且你想要计算它们。但是,该签名实际上给了我们一些东西:它指出内置的Javaslang收集器不直接收集到Javaslang Map(至少不在HashMap中)。知道这一点,我们可以找到将Java Map转换为Javaslang映射的方法,我们将会发现:

      

    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找到所有没有限定符的方法。

    此片段将收集到普通的Java Map,并且最后一步将调用收集器的Finisher,它将把来自Java Map的所有值放入Javaslang映射。

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

答案 2 :(得分:2)

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

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

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

此处ArrayMapjavaslang.collection导入。

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