如何将 Scala Case Class 转换为 Java HashMap

How To Convert Scala Case Class to Java HashMap

我正在使用 Mule ESB(基于Java)并且我有一些可以修改和创建数据的 Scala 组件。我的数据在案例 类 中表示。我正在尝试将它们转换为 Java,但是仅仅让它们转换为 Scala 类型是一个挑战。这是我正在尝试做的一个简化示例:

package com.echostar.ese.experiment


import scala.collection.JavaConverters

case class Resource(guid: String, filename: String)
case class Blackboard(name: String, guid:String, resource: Resource)

object CCC extends App {
    val res = Resource("4alskckd", "test.file")
    val bb = Blackboard("Test", "123asdfs", res)

    val myMap = getCCParams(bb)
    val result = new java.util.HashMap[String,Object](myMap)
    println("Result:"+result)

    def getCCParams(cc: AnyRef) =
        (Map[String, Any]() /: cc.getClass.getDeclaredFields) {(a, f) =>
            f.setAccessible(true)
            val value = f.get(cc) match {
                //  this covers tuples as well as case classes, so there may be a more specific way
                case caseClassInstance: Product => getCCParams(caseClassInstance): Map[String, Any]
                case x => x
            }
            a + (f.getName -> value)
        }
}

当前错误: 递归方法需要 return 类型。

我的 Scala Foo 不是很强大。我从另一个答案中获取了这个方法 here 并且基本上知道它在做什么,但还不足以将其更改为 java.util.HashMap 和 java.util.List

预期输出:

Result:{"name"="Test", "guid"="123asdfs", "resource"= {"guid"="4alskckd", "filename"="test.file"}}

更新 1: 1. 根据@cem-catikkas 将 getCCParams(caseClassInstance): Map[String, Any] 添加到上面的第 22 行。 IDE 语法错误仍然显示 "recursive method ... needs result type" 和 "overloaded method java.util.HashMap cannot be applied to scala.collection.immutable.Map"。 2. 更改 java.util.HashMap[String, Object]

您应该按照错误提示进行操作。由于 getCCParams 是一种递归方法,因此您需要声明其 return 类型。

def getCCParams(cc: AnyRef): Map[String, Any]

我想知道您是否考虑过反过来,在您的案例 class 中实现 java.util.Map 接口?这样您就不必来回转换,但任何使用 Map 接口的下游消费者都可以正常工作(例如,如果您使用 Groovy 的字段点表示法)。

回答这个问题以防其他人遇到这个问题(就像我遇到的那样)。

我相信您遇到的错误与以下事实有关 return 类型是在方法调用(第 22 行)时声明的,但是编译器在方法声明时期望它(在您的案例,第 17 行)。以下似乎有效:

def getCCParams(cc: AnyRef): Map[String, Any] = ...

关于从 Scala Map 到 Java HashMap 的 转换,通过将 ._ 通配符添加到 JavaConverters import 语句,您管理将对象的所有方法作为单个标识符导入,这是隐式转换的要求。这将包括 asJava 方法,该方法可用于将 Scala Map 转换为 Java 映射,然后可将其传递给 java.util.HashMap(Map<? extends K,? extends V> m) 构造函数以实例化 HashMap:

import scala.collection.JavaConverters._
import java.util.{HashMap => JHashMap}

...

val myMap = getCCParams(bb)
val r = myMap.asJava    // converting to java.util.Map[String, Any]
val result: JHashMap[String,Any] = new JHashMap(r)