Scala:有没有像我在Java中那样使用PriorityQueue的方法?

时间:2009-04-25 16:18:16

标签: scala priority-queue comparator

我有一个类,我想在scala.collection.mutable.PriorityQueue中使用,但我不想让它为了这个目的而订购[A]。我不认为我想要使用的顺序是PriorityQueue作为类的自然顺序。

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

所以,在我的PriorityQueue中,我希望通过'sequence'来排序这些值。然而,仅仅因为两个对象具有相同的序列并不能使它们自然相等,因为它们的“值”的内容可能不同。

这就是在Java中,能够为PriorityQueue提供备用Comparator对象的好处。我的比较器只是根据它们的“序列”对对象进行排序,并忽略它们的“值”。

必须使用“A<%Ordered [A]”参数化PriorityQueue类

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

从我读过的内容来看,这意味着我的班级必须扩展Ordered [A]或者我必须提供一个“隐式def”类型转换为Ordered [A],老实说,这种转换感觉不够优雅。

Java解决方案似乎更具“功能性”,允许我传递一个类似Comparator函数的对象,而不是强迫我进入类层次结构或monkeypatching我的类。

我意识到有使用PrioirityQueue的替代品,但我觉得我可能会在这里碰到Scala的学习曲线,并且不想在没有完全探索这个设计决定的情况下放弃。

这只是Scala库中的一个不幸的决定,还是我误解了某种调用约定,使PriorityQueue更具可用性和“功能性”?

由于

4 个答案:

答案 0 :(得分:10)

语法

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

之上真的只是一个淡淡的糖
class PriorityQueue[A]()(implicit convert: A => Ordered[A]) ...

这意味着您可以编写自己的方法A =&gt;有序[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)

答案 1 :(得分:3)

A到Ordered [A]的转换函数可以起到Java比较器的作用。该函数只需在您创建PriorityQueue的范围内可见,因此它不会成为对象的“自然排序”。

答案 2 :(得分:2)

将此前的两个(正确)答案合并到可编辑的代码中:

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中编译顶级方法,一切都必须在一个对象中。

答案 3 :(得分:2)

在scala 2.8.0中,PriorityQueue更改为

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

Scala中的Ordering [A]类似于Java中的Comparator