How to convert from from java.util.Map to a Scala Map

后端 未结 4 1652
挽巷
挽巷 2021-02-07 12:58

A Java API returns a java.util.Map;. I would like to put that into a Map[String,Boolean]

So imagine w

相关标签:
4条回答
  • 2021-02-07 13:30

    A Scala String is a java.lang.String but a Scala Boolean is not a java.lang.Boolean. Hence the following works:

    import collection.jcl.Conversions._
    import collection.mutable.{Map => MMap}
    import java.util.Collections._
    import java.util.{Map => JMap}
    
    val jm: JMap[String, java.lang.Boolean] = singletonMap("HELLO", java.lang.Boolean.TRUE)
    
    val sm: MMap[String, java.lang.Boolean] = jm //COMPILES FINE
    

    But your problem is still the issue with the Boolean difference. You'll have to "fold" the Java map into the scala one: try again using the Scala Boolean type:

    val sm: MMap[String, Boolean] = collection.mutable.Map.empty + ("WORLD" -> false)
    val mm = (sm /: jm) { (s, t2) => s + (t2._1 -> t2._2.booleanValue) }
    

    Then mm is a scala map containing the contents of the original scala map plus what was in the Java map

    0 讨论(0)
  • 2021-02-07 13:32

    useJavaMap.scala

    import test._
    import java.lang.Boolean
    import java.util.{Map => JavaMap}
    import collection.jcl.MapWrapper
    
    object useJavaMap {
      def main(args: Array[String]) {
        var scalaMap : Map[String, Boolean] = Map.empty
        scalaMap = toMap(test.testing())
        println(scalaMap)
      }
    
      def toMap[K, E](m: JavaMap[K, E]): Map[K, E] = {
        Map.empty ++ new MapWrapper[K, E]() {
          def underlying = m
        }
      }
    }
    

    test/test.java

    package test;
    
    import java.util.*;
    
    public class test {
        public static Map<String, Boolean> testing() {
            Map<String, Boolean> x = new HashMap<String, Boolean>();
            x.put("Test",Boolean.FALSE);
            return x;
        }
        private test() {}
    }
    

    Commandline

    javac test\test.java
    scalac useJavaMap.scala
    scala useJavaMap
    > Map(Test -> false)
    
    0 讨论(0)
  • 2021-02-07 13:33

    At least with Scala 2.9.2 there's an easier way with the collections conversions: import "import collection.JavaConversions._" and use "toMap".

    Example:

    // show with Java Map:
    
    scala> import java.util.{Map=>JMap}
    scala> val jenv: JMap[String,String] = System.getenv()
    jenv: java.util.Map[String,String] = {TERM=xterm, ANT_OPTS=-Xmx512m ...}
    
    scala> jenv.keySet()
    res1: java.util.Set[String] = [TERM, ANT_OPTS...]
    
    // Now with Scala Map:
    
    scala> import collection.JavaConversions._
    scala> val env: Map[String,String] = System.getenv.toMap // <--- TADA <---
    env: Map[String,String] = Map(ANT_OPTS -> -Xmx512m, TERM -> xterm ...)
    
    // Just to prove it's got Scala functionality:
    
    scala> env.filterKeys(_.indexOf("TERM")>=0)
    res6: scala.collection.immutable.Map[String,String] = Map(TERM -> xterm, 
      TERM_PROGRAM -> iTerm.app, ITERM_PROFILE -> Default)
    

    It works fine with a java.util.map of String to Boolean.

    0 讨论(0)
  • 2021-02-07 13:42

    I think I have a partial answer...

    If you convert the java map to a scala map with the java types. You can then map it to a scala map of scala types:

    val javaMap = new java.util.TreeMap[java.lang.String, java.lang.Boolean]
    val temp = new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] {
        override def underlying = javaMap
    }
    val scalaMap = temp.map{
        case (k, v) => (k.asInstanceOf[String] -> v.asInstanceOf[Boolean])
    }
    

    The flaw in this plan is that the type of scalaMap is Iterable[(java.lang.String, Boolean)] not a map. I feel so close, can someone cleverer than me fix the last statement to make this work?!

    0 讨论(0)
提交回复
热议问题