Назначение карты Java Scala с типом Any для переменной Java

1

У меня есть переменная Scala типа Map [String, Any].

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();

Изображение 174551

Используя IntelliJ, у меня слишком много вариантов, я просто выбрал scala.collection.immutable.Map, но я не знаю, как настроить Any.

Теги:

2 ответа

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 не поддерживает примитивные типы в них, так как любой тип T для JVM всегда поворачивается (стирается) к Object.

Больше, чем этот scala.collection.immutable.Map<String, Object> работает без каких-либо явных преобразований:

//Scala
class A {
  val a = Map[String, Any]("a" -> 1) //it '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 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 type - not AnyRef) и AnyRef как Object Java, но не наоборот (Object Java представлен как AnyRef). Формальный тип Int может быть представлен как int и Integer и т.д.

PS О scala автоматическом боксе для дженериков (например, Int внутри generic всегда будет отображаться как вложенное в Integer если оно передано в общий) - единственным исключением являются специализированные методы, но они просто генерируют дополнительные перегруженные unboxed-реализации, поэтому вызов с Java должно быть безопасным в любом случае (так как именно метод, который принимает/возвращает AnyRef будет AnyRef).

0

Any Java нет ни одного; это scala-специфический тип. Map Java может иметь только значения 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню