Converting Scala Nested Types to Java Types

I am currently dealing with an AWS Java SDK that expects Java types.

I used JavaConvertersto explicitly convert types, such as maps and lists, to java. I came across more complex types and found that I had to go into cards that became cumbersome.

My current problem: I have Map[String, List[String]]converting a shared object to java is simple, but it erases me when the type erases when the template matches the list on the map.

val t = m.map{
    case (k, v: List[String]) => k -> v //type erasure so unreachable
}

I found a great explanation of type tags in Scala, which is an elegant solution that I would like to implement. Scala: what is TypeTag and how to use it?

I just don’t know how I implement this in my template.

I implemented a method that looks like this

def isNestedMap[A : TypeTag](xs: A): Boolean = typeOf[A] match {
    case t if t =:= typeOf[Map[String, List[String]]] => true
    case t => false
}

case (k, v) if isNestedMap(v) => k -> "beans", false, Any.

, ? java?

.

EDIT: Map[String, Any], Any, Java

+4
3

EDIT: [String, Any], Any, Java

TypeTag , , isNestedMap(v), v: Any isNestedMap[Any](v)(typeTag[Any]).

Java?

-

def deepAsJava(x: Any): Any = x match {
  case l: List[_] => l.map(deepAsJava).asJava
  case m: Map[_, _] => m.map { case (k, v) => (k, deepAsJava(v)) }.asJava
  case ... // other collections you want to support
  case x => x
}

listDeepAsJava .., :

def deepAsJava(x: Any): Any = x match {
  case l: List[_] => listDeepAsJava(l)
  case m: Map[_, _] => mapDeepAsJava(m)
  case ... // other collections you want to support
  case x => x
}

def listDeepAsJava(x: List[Any]): java.util.List[Any] = l.map(deepAsJava).asJava
...
+1

, . REPL, :

scala> import collection.JavaConverters._
import collection.JavaConverters._

scala> List(1,2,3).asJava
res0: java.util.List[Int] = [1, 2, 3]

scala> Map(1 -> List(1),2 -> List(2))
res1: scala.collection.immutable.Map[Int,List[Int]] = Map(1 -> List(1), 2 -> List(2))

scala> res1.asJava
res2: java.util.Map[Int,List[Int]] = {1=List(1), 2=List(2)}

scala> res1.map{ case (l,r) => l -> r.asJava}.asJava
res3: java.util.Map[Int,java.util.List[Int]] = {1=[1], 2=[2]}

scala> res1.mapValues(_.asJava).asJava
res5: java.util.Map[Int,java.util.List[Int]] = {1=[1], 2=[2]}
+2

Try with Arrayinstead List.

val m = Map[String, Array[String]]()
val t = m.map{
    case (k, v: Array[String]) => k -> v //no type erasure
}
0
source

Source: https://habr.com/ru/post/1621463/


All Articles