如何在Scala中为TreeSet分配订单而不重复自己

时间:2011-03-27 21:33:07

标签: scala scala-collections treeset sortedset

我有Scala代码段,它定义了一个排序并将其应用于TreeSet。这部分编译得很好。

val acctOrdering = new Ordering[Account] {
  def compare(acc1: Account, acc2: Account) {

    // code to compare based on various criteria

  }
}

private var accountSet = new TreeSet[Account]()(acctOrdering)

在代码中的其他地方,我想得到集合中的第一个元素(如果第一个元素没有产生我想要的东西,后来又得到后续元素,尽管通常不需要),基于我之前指定的订单。我认为以下内容可行,但它没有编译:

val firstAccount = accountSet.min

错误为"could not find implicit value for parameter cmp: Ordering[Account]"

但是,如果我在要求最小值时再次指定订购对象,则会编译:

val firstAccount = accountSet.min(acctOrdering)

我认为它会自动使用我在构造时给出的顺序,并在添加到集合时逐步进行排序,因此在调用min时我不必再次指定顺序。

我做错了什么?我是否需要在某处明确定义隐式函数?

1 个答案:

答案 0 :(得分:10)

发生的事情是你假设min取决于集合的顺序,但事实并非如此。具体来说,minmax是几乎任何集合都可用的通用方法,它们采用隐式Ordering参数。

但是,如果您尝试使用firstKeylastKey这些SortedSet特定方法,它们将无需传递任何隐含的工作。

修改

您可能提出的一个问题是,如何确保Account类型可以通过任何期望Ordering的方法进行排序。您可以通过在Account的对象伴随中放置隐式定义来实现,如下所示:

object Account {
  implicit val ord = new Ordering[Account] {
    def compare(ac1: Account, acc2: Account): Int = {
      // code to compare based on various criteria
    }
  }
}

一旦这样做,您就不需要明确传递顺序。