我需要一个方法,它获取 java Map 并将其转换为 scala 不可变 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
提供:scala .Predef.$less$colon$less
我需要使用Java语言解决这个问题,但我无法编写任何Scala代码
upd:我也尝试过强制转换,但我得到了 java.lang.ClassCastException: java.util.HashMap 无法强制转换为 scala.collection.immutable.Map
最佳答案
我编写了以下 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 打交道,那也没关系。但这些问题可以通过以下方式更容易解决:
- 定义接口(interface):
interface JavaToScalaAdapters {
// ...
}
- 在 Scala 中将其实现为顶级类,没有构造函数参数、全局变量等
class JavaToScalaAdaptersImpl extends JavaToScalaAdapters {
// ...
}
- 在 Java 中调用
new
来获取此实现,并像任何其他 Java 代码一样调用它
JavaToScalaAdapters adapters = new JavaToScalaAdaptersImpl();
它可能是所有公司 Java 项目中使用的单个工件,这些项目依赖 Scala,即使他们不想这样做。任何其他解决方案都会浪费大量时间和金钱。即使这是一种一次性解决方法,用 Scala 编写、编译并将 .class
文件放入版本控制中的资源目录中,也比对代码进行逆向工程更快。此类逆向工程唯一合理的情况是学习或开发一些低级实用程序。
关于java - 在java中将java映射转换为scala不可变映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77023755/