WedX - журнал о программировании и компьютерных науках

Java SortedMap в Scala TreeMap

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

  • (Отредактировано.) Каким образом два сравниваемых объекта должны упорядочиваться? Я не совсем понимаю. Ключи должны быть упорядочены в TreeMap. Это ключи Comparable []. Значит, вам нужно заказать аналоги. Итак, вам нужен заказ [Сопоставимый []]. 29.01.2010

Ответы:


1

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

// 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)
30.01.2010
  • Я думаю, что всегда, когда это возможно, предпочтительнее неявное преобразование в упорядоченное. Последний будет вызываться для каждого сравнения, необходимого для сортировки или другого алгоритма, чувствительного к порядку. 30.01.2010
  • Спасибо ретроним. К сожалению, я не знаю типа, что делает эту проблему немного сложной. Однако написанный вами код отлично работает. 01.02.2010

  • 2

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

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

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

    12.12.2012
    Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]