Scala 扩展排序以容纳类对象时发生PriorityQueue varargs错误
我的目标是创建一个函数,该函数在初始化包含所述对象的PriorityQueue时接受2个或更多对象的varargs 有关守则如下:Scala 扩展排序以容纳类对象时发生PriorityQueue varargs错误,scala,variadic-functions,priority-queue,Scala,Variadic Functions,Priority Queue,我的目标是创建一个函数,该函数在初始化包含所述对象的PriorityQueue时接受2个或更多对象的varargs 有关守则如下: case class Topic(topic: String, usageFrequency: Long = 1) object FreqOrdering extends Ordering[Topic] { def compare(a: Topic, b:Topic) = -(a.usageFrequency compare b.usageFrequenc
case class Topic(topic: String, usageFrequency: Long = 1)
object FreqOrdering extends Ordering[Topic] {
def compare(a: Topic, b:Topic) = -(a.usageFrequency compare b.usageFrequency)}
def initPriQu(a : Topic, b: Topic, c: Topic*): PriorityQueue[Topic] = {
return PriorityQueue(a,b,c)(FreqOrdering)}
sbt中的错误(Scala 2):
找到[错误]:TopicRenderInit.FreqOrdering.type[错误]必填项:scala.math.Ordering[等于]
[错误]注意:TopicTrenderInit.Topic问题是,当您将
a、b、c
传递到PriorityQueue
的工厂时。编译器看到的是,您传递了三个A
类型的参数,这些树之间唯一的超级类型是Equals
这是因为
a
和b
是主题
,它作为一个case类扩展了Equals
,而c
是Seq[Topic]
类型(varargs参数作为Seq
传递),它也扩展了Equals
这就是为什么它要求对[Equals]进行排序 您可以按如下方式进行修复。
(注意,这是相当丑陋的,可能是有害的,您可以考虑只接收一个VARARGS而不是<代码> A<代码> <代码> B<代码>然后<代码> C <代码> < /P>
问题是,当您将
a、b、c
传递到PriorityQueue
的工厂时。编译器看到的是,您传递了三个A
类型的参数,这些树之间唯一的超级类型是Equals
这是因为
a
和b
是主题
,它作为一个case类扩展了Equals
,而c
是Seq[Topic]
类型(varargs参数作为Seq
传递),它也扩展了Equals
这就是为什么它要求对[Equals]进行排序 您可以按如下方式进行修复。
(注意,这是相当丑陋的,可能是有害的,您可以考虑只接收一个VARARGS而不是<代码> A<代码> <代码> B<代码>然后<代码> C <代码> < /P>
问题在于构建
PriorityQueue
的方式。您将向它传递两个Topic
类型的值和一个Seq[Topic]
类型的值,因此结果是PriorityQueue[Any]
这应该起作用:
def initPriQu(a : Topic, b: Topic, c: Topic*): mutable.PriorityQueue[Topic] =
mutable.PriorityQueue(Seq(a, b) ++ c:_*)(FreqOrdering)
另外,不要使用
return
问题在于构建优先级队列的方式。您将向它传递两个Topic
类型的值和一个Seq[Topic]
类型的值,因此结果是PriorityQueue[Any]
这应该起作用:
def initPriQu(a : Topic, b: Topic, c: Topic*): mutable.PriorityQueue[Topic] =
mutable.PriorityQueue(Seq(a, b) ++ c:_*)(FreqOrdering)
另外,在性能方面不要使用return
(并且知道Seq在运行时可能是一个列表),将两个Seq连接起来还是使用flatten?@LuisMiguelMejíaSuárez,我认为对于List
来说,最快的实现将是a+:b+:c:.*
,因为它将使用+:
来自List
的:
作为的包装,这是O(1)
。但是,对于其他基础集合,性能可能非常差,因为可能需要两个副本。这里为列表建议的++
是:
的包装器,它也很好,不会为其他可能的类型做出任何重大牺牲。如果你的flatten
在任何类中都没有被覆盖,那么根本就没有优化,事实上,在flatten
@SergGr中添加优化是很困难的。搜索了一点之后,我发现varargs是使用WrappedArray
而不是列表来实现的,因此,是的,Tim使用++
的解决方案将是最好的。我会更新我的答案来使用它。谢谢你,所有这些评论都很有启发性。不使用return关键字的原因是什么?它是为了更好的可读性还是为了更实用的原因?@a.Lopez返回的问题在于在简单的情况下它是不必要的,在复杂的情况下可能会有意外的行为。在简单的情况下,您可以使用表达式作为返回值。在复杂的情况下,它可以跳出多个嵌套块,而且它跳转到哪里并不总是很清楚!就性能而言(并且知道Seq在运行时可能是一个列表),将两个Seq连接起来还是使用flatte更好?@LuisMiguelMejíaSuárez,我认为对于List
来说,最快的实现将是a+:b+:c:.*
,因为它将使用+:
来自List
的:
作为的包装,这是O(1)
。但是,对于其他基础集合,性能可能非常差,因为可能需要两个副本。这里为列表建议的++
是:
的包装器,它也很好,不会为其他可能的类型做出任何重大牺牲。如果你的flatten
在任何类中都没有被覆盖,那么根本就没有优化,事实上,在flatten
@SergGr中添加优化是很困难的。搜索了一点之后,我发现varargs是使用WrappedArray
而不是列表来实现的,因此,是的,Tim使用++
的解决方案将是最好的。我会更新我的答案来使用它。谢谢你,所有这些评论都很有启发性。不使用return关键字的原因是什么?它是为了更好的可读性还是为了更实用的原因?@a.Lopez返回的问题在于在简单的情况下它是不必要的,在复杂的情况下可能会有意外的行为。在简单的情况下,您可以使用表达式作为返回值。在复杂的情况下,它可以跳出多个嵌套块,而且它跳转到哪里并不总是很清楚!