Implicit conversion between java and scala collections using JavaConversions

后端 未结 2 1049
感情败类
感情败类 2021-01-29 00:02

I merged a scala Set of scala Maps using a generic function

def mergeMaps[A, B](ms: Set[Map[A, B]])(f: (B, B) => B): Map[A, B] =
(Ma         


        
相关标签:
2条回答
  • 2021-01-29 00:19

    They say to try JavaConverters, as JavaConversions is deprecated.

    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]
    

    Perhaps to show why it's deprecated:

    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)) {
                                        ^
    

    Noting that the for comprehension yields a set of pairs.

    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)]
    

    Apparently inference fails to both do the conversion and then figure out the op types.

    Sometimes breaking apart the expression assists inference, but not here.

    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) }
         | }
    
    0 讨论(0)
  • 2021-01-29 00:28

    Would a JavaConverter do what you want?

    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()
    
    0 讨论(0)
提交回复
热议问题