5

scala.collection.mutable.PriorityQueue で使用したいクラスがありますが、この 1 つの目的のためだけに Ordered[A] にしたくありません。PriorityQueue に関して使用したい順序を、クラスの自然な順序とは見なしません。

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

したがって、私の PriorityQueue では、値を「順序」で並べ替えたいと思います。ただし、2 つのオブジェクトが同じシーケンスを持っているからといって、それらの「値」の内容が異なる可能性があるため、それらが自然に等しくなるわけではありません。

ここで、Java では、別の Comparator オブジェクトを PriorityQueue に提供できると便利です。私の Comparator は、単に「シーケンス」に関してオブジェクトを並べ替え、それらの「値」を無視します。

PriorityQueue クラスは、「A <% Ordered[A]」でパラメータ化する必要があります

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

私が読んだことから、これは、私のクラスが Ordered[A] を拡張する必要があるか、Ordered[A] への「暗黙的な定義」型変換を提供する必要があることを意味します。

Java ソリューションはより「機能的」であるように思われ、クラス階層に強制的に参加させたり、クラスにモンキーパッチを適用したりする代わりに、Comparator 関数のようなオブジェクトを渡すことができます。

PrioirityQueue の使用に代わる方法があることは理解していますが、ここで Scala の学習曲線にぶつかりそうで、この設計上の決定を十分に検討せずにあきらめたくありません。

これは Scala ライブラリでの不幸な決定にすぎないのでしょうか、それとも PriorityQueue をより使いやすく「機能的」にする何らかの呼び出し規約を誤解しているのでしょうか?

ありがとう

4

4 に答える 4

10

構文

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)
于 2009-04-25T18:53:05.447 に答える
3

AからOrdered[A]への変換関数は、Javaコンパレータの役割を果たすことができます。この関数は、PriorityQueueを作成するスコープでのみ表示される必要があるため、オブジェクトの「自然な順序」にはなりません。

于 2009-04-25T18:25:16.217 に答える
2

scala 2.8.0 では、PriorityQueue は次のように変更されます。

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

また、Scala の Ordering[A] は Java の Comparator に似ています

于 2009-11-16T09:55:53.980 に答える