Java SortedMap в Scala TreeMap - PullRequest
       15

Java SortedMap в Scala TreeMap

3 голосов
/ 29 января 2010

У меня проблемы с преобразованием 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))  })

Ответы [ 2 ]

2 голосов
/ 30 января 2010

Во-первых, чтобы уточнить вашу ошибку:

// 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)
0 голосов
/ 12 декабря 2012

Возможно, вы также можете просто указать явный тип TreeMap. Вот как я только что решил похожую проблему:

collection.immutable.TreeMap[whatever,whatever]() ++ ...

(Извините, у меня нет времени, чтобы проверить, как именно это относится к источникам, опубликованным в вопросе.)

...