首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Java SortedMap到Scala TreeMap

从Java SortedMap到Scala TreeMap
EN

Stack Overflow用户
提问于 2010-01-30 01:48:07
回答 2查看 1.8K关注 0票数 3

我在将java SortedMap转换为scala TreeMap时遇到了问题。SortedMap来自反序列化,在使用之前需要转换为scala结构。

对于好奇的人来说,一些背景知识是序列化的结构是通过XStream编写的,在期望时,我注册了一个转换器,它告诉我任何可以赋值给SortedMap[Comparable[_],_]的东西都应该给我。因此,我的convert方法被调用,并被赋予一个Object,我可以安全地转换它,因为我知道它是SortedMap[Comparable[_],_]类型。这就是有趣的地方。这里有一些示例代码,可能有助于解释它。

代码语言:javascript
复制
// 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))  })
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-01-30 18:51:51

首先,为了澄清你的错误:

代码语言:javascript
复制
// 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],如下所示。

代码语言:javascript
复制
// 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]]

然而,如果你真的不知道键的类型,我不认为你可以用Comparable#compareTo来创建Ordering,至少在没有反射的情况下是这样的:

代码语言:javascript
复制
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)
票数 2
EN

Stack Overflow用户

发布于 2012-12-13 01:02:00

您也可以只为TreeMap指定一个显式类型。这就是我刚刚解决了一个类似的问题:

代码语言:javascript
复制
collection.immutable.TreeMap[whatever,whatever]() ++ ...

(抱歉,我没有时间检查这是否适用于问题中发布的来源。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2163925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档