您可以对可变Scala集合进行适当排序吗?
是否可以就地对ArrayBuffer或其他可变Scala集合进行排序?我看到ArrayBuffer.sorted(和sortBy)返回一个新集合,Sorting.quicksort对数组进行排序,但对ArrayBuffer不起作用 我问这个问题的原因是,我在Spark中使用combineByKey来构建大小有限的评分对象集合(如按键排列的“前十名”列表)。如果我合并到一个新对象中,并且集合已经满负荷,我需要删除得分最低的对象。我可以使用排序的集合,如PriorityQueue或SortedSet,但我不需要一直对集合进行排序,只在集合已满的情况下您可以对可变Scala集合进行适当排序吗?,scala,sorting,collections,Scala,Sorting,Collections,是否可以就地对ArrayBuffer或其他可变Scala集合进行排序?我看到ArrayBuffer.sorted(和sortBy)返回一个新集合,Sorting.quicksort对数组进行排序,但对ArrayBuffer不起作用 我问这个问题的原因是,我在Spark中使用combineByKey来构建大小有限的评分对象集合(如按键排列的“前十名”列表)。如果我合并到一个新对象中,并且集合已经满负荷,我需要删除得分最低的对象。我可以使用排序的集合,如PriorityQueue或SortedSet
那么,是否有某种方法可以对ArrayBuffer或ListBuffer进行适当的排序?或者是否有其他支持附加和排序的集合?我确信有更好的方法可以做到这一点,但我对Scala还是新手。您可以使用Java的排序实用程序 以下是一个例子:
val myArray = Array(1,12,5,6)
java.util.Arrays.sort(myArray)
在REPL上:
> myArray
res3: Array[Int] = Array(1, 5, 6, 12)
如果您拥有的是ScalaArrayBuffer
,则调用toArray
将其转换为数组
当然,
ArrayBuffer
上的toArray
会导致再次处理整个缓冲区的成本。如果这样做成本高昂,请检查是否可以在数组中而不是在数组缓冲中获得初始结果。如果结果长度固定且不太可能增长,则不需要使用ArrayBuffer的动态扩展功能
目前没有用于排序集合的工具。也就是说,如果您希望极少进行排序,您可以分别研究支持这两种方法,例如作为或[PriorityQueue[A],ArrayBuffer[A]]
;或者,如果您希望排序相当普遍,那么您应该使用一种数据结构,在这种结构中,您每次添加一个元素时都不必支付这样的罚款——这意味着只需使用SortedSet
或PriorityQueue
。否则你会很快变慢。(n^2 log n
很快就会变大,如果每次添加新元素时都进行完整排序,就会得到这种结果。)您可以使用Scala的JavaConverters
来委托给Java的数组。使用一行代码进行排序
假设在可变缓冲区中有Foo
的实例,您希望使用比较器fooparator
对其进行排序
import scala.collection.mutable
import scala.collection.JavaConverters._
…
val buffer = mutable.ArrayBuffer[Foo]()
…
buffer.asJava.sort(fooComparator) // sort "in place" (actually hides 1 copy)
然而,为了获得最佳性能,似乎无法使用ArrayBuffer
,而简单的固定大小Array
是一种选择。好消息是JavaConverters.asJava
不会复制这些项。但是Java的List.sort
方法在内部将项目复制到Array
并调用Arrays.sort
。(然后将已排序的项目分配回原始集合)
也许“完整的解决方案”是定义您自己版本的Scala的ArrayBuffer
,它公开底层数组进行排序。由于Scala的集合库是如何设置的,实现您自己的集合类型可以完成与原始集合类型相同的事情,再加上您自己在Scala中的技巧通常很容易。Related:,但不是真正的答案(在'14年有一个更新的问题结束了。不确定'15年是否带来了相关的更改),谢谢。我想我会使用反向优先队列,所以得分最低的对象在出列时首先出现。这样,如果每个键的对象数远远超过了我保留的“前十个”,我就不会与您提到的陷阱相冲突。如果您想将ArrayBuffer转换为数组,则可以使用Sorting.quicksort(myArray)对其进行排序,而无需借助Java库。但在我的例子中,我不想将缓冲区转换为固定大小的数组,因为我有更多的元素要添加到它。