在Java中将Java Map转换为Scala Immutable Map

c8ib6hqw  于 8个月前  发布在  Scala
关注(0)|答案(1)|浏览(77)

我需要一个方法,它获取java Map并将其转换为scala immutable Map。我试过这么做

import scala.Predef;
import scala.Tuple2;
import scala.collection.JavaConverters;

public static <K,V> scala.collection.immutable.Map<K,V> convert(java.util.HashMap<K,V> javaMap) {
       return JavaConverters.mapAsScalaMapConverter(javaMap).asScala().toMap(Predef.<Tuple2<K,V>>conforms());
}

但我收到以下消息
所需类型:scala.$less$colon$less<Tuple2<K,V>,scala. Tuple2 <K,V>>
提供:scala**.Predef**.$less$colon$less<Tuple2<K,V>,scala.Tuple2 <K,V>>
我需要使用Java语言来解决这个问题,我无法编写任何Scala代码upd:我也试过铸造,但我一直得到java.lang.ClassCastException: java.util.HashMap cannot be cast to scala.collection.immutable.Map

jmo0nnb3

jmo0nnb31#

我写了下面的Scala代码:

import scala.collection.JavaConverters._

class MapConversion {

  def fromScala[K, V](map: scala.collection.immutable.Map[K, V]): java.util.Map[K, V] = map.asJava

  def toScala[K, V](map: java.util.Map[K, V]): scala.collection.mutable.Map[K, V] = map.asScala
}

并将其与

scala-cli compile --scala "2.12.11" .

(JavaConverters建议使用Scala 2.12或更早版本)。
然后我在https://dmitriy-gulyaev.github.io/java-disassembler/中打开了结果MapConversion.class,尽管我也可以使用javap
阅读字节码表明,最接近的Java代码应该是类似于以下内容的代码:

class MapConversion {

  <K, V> java.util.Map<>K, V> fromScala(
    scala.collection.immutable.Map<K, V> map
  ) {
     return
        // get JavaConverters$ companion object instance
        scala.collection.JavaConverters$.MODULE$
        // use implicit conversion to wrap it in Decorators$AsJava
          .mapAsJavaConverter(map)
          // call asJava to convert the value
          .asJava 
  }

  <K, V> scala.collection.mutable.Map<K, V> toScala(
    java.util.Map<K, V> map
  ) {
    return
      // get JavaConverters$ companion object instance
      scala.collection.JavaConverters$.MODULE$
        // use implicit conversion to wrap it in Decorators$AsScala
        .mapAsScalaMapConverter(map)
        // call asScala to convert the value
        .asScala
  }
}

(免责声明:我还没试过,也不打算试)。
然而,在99%的情况下,“不使用Scala语言”的要求是很难辩护的:它忽略了正确的工具(编译器),它需要反向生成,这反过来又需要JVM如何工作的知识,并且每次进行任何更改时都需要这样的反向工程。它也没有“保存”代码库以防止“Scala污染”,因为显然Scala标准库和使用它的代码已经在依赖项中了。
如果整个公司不想处理Scala,那也没关系。但这些问题可以通过以下方式更容易地解决:
1.定义一个接口:

interface JavaToScalaAdapters {
  // ...
}

1.在Scala中将其实现为没有构造函数参数、全局变量等的顶级类

class JavaToScalaAdaptersImpl extends JavaToScalaAdapters {
  // ...
}

1.在Java中调用new以获得此实现,并像其他Java代码一样调用它

JavaToScalaAdapters adapters = new JavaToScalaAdaptersImpl();

它可以是所有公司Java项目中使用的单个工件,这些项目依赖于Scala,即使他们不想这样做。任何其他解决方案都是浪费大量时间和金钱。即使这是一个一次性的解决方案,它只是更快地编写在Scala中,编译,并抛出.class文件到资源目录中的版本控制,比反向工程的代码。只有在学习或开发一些低级实用程序的情况下,这种逆向工程才是合理的。

相关问题