【问题标题】:Implicit conversion between java and scala collections using JavaConversions使用 JavaConversions 在 java 和 scala 集合之间进行隐式转换
【发布时间】:2016-07-12 05:32:21
【问题描述】:

我使用通用函数合并了 scala Set 的 scala Maps

def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Map[A, B]() /: (for (m <- ms; kv <- m) yield kv))
{
  (a, kv) =>
  a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}

这可以处理相同键冲突的情况。但是,我想在 Scala 代码中使用 Java 集合来实现。我研究了一下,发现了JavaConversions。我导入它并写了这个

def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(new util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv))
{
  case (a, kv) =>
    a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
}

但是,它说存在类型不匹配

Error:(67, 11) type mismatch;
found   : scala.collection.mutable.Map[A,B]
required: java.util.HashMap[A,B]
    a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv)
      ^

JavaConversions不是用来将util.HashMap隐式转换为mutable.Map吗?我在这里错过了什么?

【问题讨论】:

    标签: java scala scala-collections


    【解决方案1】:

    JavaConverter 会做你想做的事吗?

    scala> import scala.collection.JavaConverters._
    import scala.collection.JavaConverters._
    
    scala> val x = (new java.util.HashMap[Int,Int]).asScala
    x: scala.collection.mutable.Map[Int,Int] = Map()
    

    【讨论】:

    【解决方案2】:

    他们说要试试 JavaConverters,因为 JavaConversions 已被弃用。

    scala> import collection.JavaConverters._
    import collection.JavaConverters._
    
    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
         | (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
         | case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
    <console>:16: error: value contains is not a member of java.util.HashMap[A,B]
           case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
                                      ^
    <console>:16: error: java.util.HashMap[A,B] does not take parameters
           case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
                                                                   ^
    <console>:16: error: type mismatch;
     found   : (A, B)
     required: String
           case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
                                                                                        ^
    <console>:15: error: type mismatch;
     found   : java.util.HashMap[A,B]
     required: Map[A,B]
           (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
                                        ^
    
    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
         | (new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
         | case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
    <console>:15: error: type mismatch;
     found   : scala.collection.mutable.Map[A,B]
     required: scala.collection.immutable.Map[A,B]
           (new java.util.HashMap[A, B].asScala /: (for (m <- ms; kv <- m) yield kv)) {
                                                ^
    
    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
         | (new java.util.HashMap[A, B].asScala.toMap /: (for (m <- ms; kv <- m) yield kv)) {
         | case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
    mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)Map[A,B]
    

    也许是为了说明它被弃用的原因:

    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
         | (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
         | case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
    <console>:19: error: type mismatch;
     found   : scala.collection.mutable.Map[A,B]
     required: java.util.HashMap[A,B]
           case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
                             ^
    <console>:18: error: type mismatch;
     found   : java.util.HashMap[A,B]
     required: Map[A,B]
           (new java.util.HashMap[A, B] /: (for (m <- ms; kv <- m) yield kv)) {
                                        ^
    

    注意 for 推导会产生一组对。

    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B) = for (m <- ms; kv <- m) yield kv
    mergeMaps: [A, B](ms: Set[Map[A,B]])(f: (B, B) => B)scala.collection.immutable.Set[(A, B)]
    

    显然推理无法进行转换,然后找出操作类型。

    有时拆分表达式有助于推理,但不是在这里。

    scala> def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] = {
         | val ss = for (m <- ms; kv <- m) yield kv
         | (new java.util.HashMap[A, B] /: ss) {
         | case (a, kv) => a + (if (a.contains(kv._1)) kv._1 -> f(a(kv._1), kv._2) else kv) }
         | }
    

    【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2011-09-30
    • 1970-01-01
    • 2011-01-10
    • 2014-08-28
    • 2015-10-28
    • 1970-01-01
    • 2018-08-06
    相关资源
    最近更新 更多