Scala: есть ли способ использовать PriorityQueue, как я бы в Java? - PullRequest
5 голосов
/ 25 апреля 2009

У меня есть класс, который я хотел бы использовать в scala.collection.mutable.PriorityQueue, но я не хочу делать его Упорядоченным [A] только для этой цели. Я не считаю упорядочение, которое я хочу использовать в отношении PriorityQueue, естественным упорядочением класса.

class MyObject (sequence: Int, values: List[String]) ...

Итак, в моем PriorityQueue я бы хотел, чтобы значения упорядочивались по «последовательности». Однако тот факт, что два объекта имеют одинаковую последовательность, не делает их естественно равными, поскольку содержимое их «значений» может быть разным.

Здесь, в Java, приятно иметь возможность предоставить альтернативный объект Comparator в PriorityQueue. Мой Comparator просто упорядочивал объекты по их «последовательности» и игнорировал их «значения».

Класс PriorityQueue должен быть параметризован с помощью «A <% Ordered [A]» </p>

class PriorityQueue[A <% Ordered[A]] extends ... 

Из того, что я прочитал, это означает, что мой класс должен расширять Ordered [A], или я должен обеспечить преобразование типа "неявное определение" в Ordered [A], что, честно говоря, выглядит не элегантно.

Решение Java кажется более «функциональным», позволяя мне передавать объект, похожий на функцию Comparator, вместо того, чтобы заставлять меня переходить в иерархию классов или обезличивать мой класс.

Я понимаю, что есть альтернативы использованию PrioirityQueue, но я чувствую, что могу столкнуться с кривой обучения Scala здесь и не хочу сдаваться, не изучая полностью это дизайнерское решение.

Является ли это просто неудачным решением в библиотеке Scala, или я неправильно понимаю какое-то соглашение о вызовах, которое делает PriorityQueue более удобным и «функциональным»?

Спасибо

Ответы [ 4 ]

10 голосов
/ 25 апреля 2009

Синтаксис

class PriorityQueue[A <% Ordered[A]] ...

на самом деле просто легкий сахар на вершине

class PriorityQueue[A]()(implicit convert: A => Ordered[A]) ...

Это означает, что вы можете написать свой собственный метод A => Ordered [A]

case class Foo(n: Int)
def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] {
  def compare(other: Foo) = f.n.compare(other.n)
}

И вручную передать его в конструктор PriorityQueue

new PriorityQueue[Foo]()(orderedFoo)
3 голосов
/ 25 апреля 2009

Функция преобразования A в Упорядоченный [A] может играть роль компаратора Java. Функция должна быть видимой только в области, в которой вы создаете PriorityQueue, поэтому она не станет "естественным упорядочением" для вашего объекта.

2 голосов
/ 16 ноября 2009

В Scala 2.8.0 PriorityQueue изменяется на

class  PriorityQueue[A](implicit ord : Ordering[A]) 

А порядок [A] в Scala похож на Comparator в Java

2 голосов
/ 26 апреля 2009

Объединение обоих (правильных) ответов до этого в скомпилированный код:

object o {
  case class Foo(n: Int)
  implicit def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] {
    def compare(other: Foo) = f.n.compare(other.n)
  }

  val x = new scala.collection.mutable.PriorityQueue[Foo]()
}

Его пример не скомпилируется для вас только потому, что (я полагаю) вы бросили его в компилятор как есть. Вы не можете компилировать методы верхнего уровня в Scala, все должно быть в объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...