我无法将java SortedMap转换为scala TreeMap。 SortedMap来自反序列化,需要在使用之前转换为scala结构。
好奇的一些背景是,序列化结构是通过XStream编写的,并且在进行干预时我会注册一个转换器,该转换器应该向我提供任何可以分配给SortedMap[Comparable[_],_]
的内容。所以我的convert方法被调用并被赋予Object
,我可以安全地进行投射,因为我知道它的类型为SortedMap[Comparable[_],_]
。这就是它变得有趣的地方。以下是一些可能有助于解释它的示例代码。
// a conversion from comparable to ordering
scala> implicit def comparable2ordering[A <: Comparable[A]](x: A): Ordering[A] = new Ordering[A] {
| def compare(x: A, y: A) = x.compareTo(y)
| }
comparable2ordering: [A <: java.lang.Comparable[A]](x: A)Ordering[A]
// jm is how I see the map in the converter. Just as an object. I know the key
// is of type Comparable[_]
scala> val jm : Object = new java.util.TreeMap[Comparable[_], String]()
jm: java.lang.Object = {}
// It's safe to cast as the converter only gets called for SortedMap[Comparable[_],_]
scala> val b = jm.asInstanceOf[java.util.SortedMap[Comparable[_],_]]
b: java.util.SortedMap[java.lang.Comparable[_], _] = {}
// Now I want to convert this to a tree map
scala> collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k)) })
<console>:15: error: diverging implicit expansion for type Ordering[A]
starting with method Tuple9 in object Ordering
collection.immutable.TreeMap() ++ (for(k <- b.keySet) yield { (k, b.get(k)) })
答案 0 :(得分:2)
首先,澄清你的错误:
// The type inferencer can't guess what you mean, you need to provide type arguments.
// new collection.immutable.TreeMap
// <console>:8: error: diverging implicit expansion for type Ordering[A]
//starting with method Tuple9 in object Ordering
// new collection.immutable.TreeMap
// ^
您可以编写隐式信息,将Comparable[T]
视为Ordering[T]
,如下所示。
// This implicit only needs the type parameter.
implicit def comparable2ordering[A <: Comparable[A]]: Ordering[A] = new Ordering[A] {
def compare(x: A, y: A) = x.compareTo(y)
}
trait T extends Comparable[T]
implicitly[Ordering[T]]
但是,如果你真的不知道密钥的类型,我认为你不能用Ordering
创建Comparable#compareTo
,至少没有反思:
val comparableOrdering = new Ordering[AnyRef] {
def compare(a: AnyRef, b: AnyRef) = {
val m = classOf[Comparable[_]].getMethod("compareTo", classOf[Object])
m.invoke(a, b).asInstanceOf[Int]
}
}
new collection.immutable.TreeMap[AnyRef, AnyRef]()(comparableOrdering)
答案 1 :(得分:0)
您也可以为TreeMap提供一个显式类型。这就是我刚刚解决类似问题的方法:
collection.immutable.TreeMap[whatever,whatever]() ++ ...
(对不起,我没时间检查这究竟是如何适用于问题中发布的来源。)