我有一个类型为Map [String,Any]的Scala变量。
object Maps
{
var no_string: Map[String, Any] = Map(
...
我还有一个使用此类型作为参数的Scala方法。
def generateContext(rep: Map[String, Any], m: Int, k: Int, q: Int) : Array[Byte]
在Java中,我可以使用如下类型调用方法。
wifi.generateContext(Maps.no_string(), m, k, q);
然后,如何将Maps.no_string()
存储到Java变量中?换句话说,我需要用什么类型来存储它们?
Map(???)[String, Any(???)] x = Maps.no_string();
使用IntelliJ,我有太多选项,我只选择了scala.collection.immutable.Map
,但我不知道如何设置Any
。
答案 0 :(得分:2)
您需要将其“转换”为Map[String, AnyRef]
,对应scala.collection.immutable.Map<String, Object>
:
scala> val a: Map[String, Any] = Map("a" -> 1)
a: Map[String,Any] = Map(a -> 1)
scala> val b: Map[String, AnyRef] = a.asInstanceOf[Map[String, AnyRef]]
b: Map[String,AnyRef] = Map(a -> 1)
scala> b("a") //no ClassCastException as there is nothing to cast
res7: AnyRef = 1
通用类型的装箱在Scala中自动完成,其中包含Java doesn't support基元类型,因为JVM的任何类型T
始终被转换(擦除)到Object
。
除了scala.collection.immutable.Map<String, Object>
以外,没有任何明确的转化:
//Scala
class A {
val a = Map[String, Any]("a" -> 1) //it's `Any` but fits to AnyRef/Object
}
//Java
public class B {
public static void main(String[] args) {
A a = new A();
scala.collection.immutable.Map<String, Object> map = a.a(); //it's AnyRef/Object and btw fits only to AnyRef if you'd try to use it from Scala
System.out.println("Hello World!" + map.apply("a"));
}
}
打印:
Hello World!1
显然,scala代表Any
(完全正式Any
类型 - 不是子类型)和AnyRef
代表Java Object
,但反之亦然(Java Object
}仅表示为AnyRef
。正式Int
类型可以由int
或Integer
表示,依此类推。
P.S。关于scala的泛型自动装箱(例如,泛型中的Int
将始终表示为盒装Integer
,如果它被传递给泛型) - 唯一的例外是专门的方法,但它们只是生成额外的重载未装箱实现,所以来自Java的调用无论如何都应该是安全的(正如选择/返回AnyRef
的方法一样)。
答案 1 :(得分:0)
Any
;它是特定于scala的类型。 Java的Map
只能有Object
个值(对应于scala的AnyRef
),而不是原语,因此您需要进行更仔细的转换:
val m = Map[String, Any]("a" -> 1, "b" -> "two")
import scala.collection.JavaConverters._
val javaMap: java.util.Map[String, java.lang.Object] =
m.mapValues {
case x: AnyRef => x: java.lang.Object
case x: Int => Integer.valueOf(x)
// etc for other primatives...
}.asJava