Scala:有没有办法像在 Java 中一样使用 PriorityQueue?

发布于 2024-07-19 03:49:46 字数 873 浏览 1 评论 0原文

我有一个类,我想在 scala.collection.mutable.PriorityQueue 中使用,但我不想仅出于此目的将其设为 Ordered[A]。 我不认为我想要使用的 PriorityQueue 排序是类的自然排序。

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

因此,在我的 PriorityQueue 中,我希望值按“序列”排序。 然而,仅仅因为两个对象具有相同的序列并不意味着它们自然相等,因为它们的“值”的内容可能不同。

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

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

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

根据我的阅读,这意味着我的类必须扩展 Ordered[A] 或者我必须提供到 Ordered[A] 的“隐式 def”类型转换],老实说,感觉不优雅。

Java 解决方案似乎更“实用”,允许我传递一个类似 Comparator 函数的对象,而不是强迫我进入类层次结构或对我的类进行猴子修补。

我意识到除了使用 PrioirityQueue 之外还有其他选择,但我觉得我可能会遇到 Scala 学习曲线,并且不想在没有充分探索这个设计决策的情况下放弃。

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

谢谢

I have a class that I would like to use in a scala.collection.mutable.PriorityQueue, but I don't want to make it Ordered[A] just for this one purpose. I don't consider the ordering I want to use with respect to the PriorityQueue as the natural ordering of the class.

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

So, in my PriorityQueue, I would like the values to be ordered by 'sequence'. However, just because two objects have the same sequence doesn't make them naturally equal since the contents of their 'values' may be different.

This is where, in Java, it's nice to be able to supply an alternate Comparator object to the PriorityQueue. My Comparator would simply order the objects with respect to their 'sequence' and ignores their 'values'.

The PriorityQueue class must be parameterized with a "A <% Ordered[A]"

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

From what I've read, this means my class must extend Ordered[A] or I must provide an "implicit def" type conversion to Ordered[A], which, honestly, feels inelegant.

The Java solution seems more "functional" allowing me to pass a Comparator function-like object instead of forcing me into a class hierarchy or monkeypatching my class.

I realize there are alternatives to using PrioirityQueue, but I feel like I may be bumping up against the Scala learning curve here and don't want to give up without exploring this design decision fully.

Is this just an unfortunate decision in the Scala library or am I misunderstanding some sort of calling convention that makes PriorityQueue more usable and 'functional'?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

—━☆沉默づ 2024-07-26 03:49:46

语法

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)

The syntax

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

is really just a light sugaring on top of

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

This means you can write your own method 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)
}

And manually pass it into your PriorityQueue constructor

new PriorityQueue[Foo]()(orderedFoo)
深陷 2024-07-26 03:49:46

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

The conversion function of A to Ordered[A] can play the role of Java comparator. The function needs to be visible only in the scope where you create PriorityQueue, so it's not going to become "natural ordering" for your object.

相权↑美人 2024-07-26 03:49:46

将这个之前的两个(正确)答案组合成可编译代码:

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

Combining both (correct) answers before this one into compilable code:

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]()
}

His example wouldn't compile for you only because (I am supposing) you threw it at the compiler as-is. You can't compile top level methods in scala, everything has to be in an object.

离线来电— 2024-07-26 03:49:46

在scala 2.8.0中,PriorityQueue更改为

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

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

In scala 2.8.0, the PriorityQueue changes to

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

And the Ordering[A] in Scala is similar to Comparator in Java

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文