Scala 2.8 TreeMap和自定义排序

时间:2010-04-21 14:35:57

标签: scala scala-2.8 treemap

我正在从scala 2.7切换到scala 2.8并使用订购。它看起来很直接,但我想知道我可以减少一点点冗长。例如:

scala> case class A(i: Int)
defined class A
scala> object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i}
defined module A

如果我尝试创建TreeMap,我会收到错误

scala> new collection.immutable.TreeMap[A, String]()
<console>:10: error: could not find implicit value for parameter ordering: Ordering[A]
       new collection.immutable.TreeMap[A, String]()
       ^

但是,如果我明确指定对象A作为排序,它可以正常工作。

scala> new collection.immutable.TreeMap[A, String]()(A)
res34: scala.collection.immutable.TreeMap[A,String] = Map()

我是否总是必须明确指定顺序或是否有更短的格式?

由于

3 个答案:

答案 0 :(得分:13)

请注意,创建Ordering

的方式略逊一筹
implicit val OrderingA = Ordering.by((_: A).i)

Ordering的主要优势是可以为同一个班级提供许多。如果您的A班级是真正的Ordered,那么您应该扩展它。如果不是,您可以明确地传递订单:

,而不是使用含义
new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))

答案 1 :(得分:10)

注意诊断中的“隐含”一词。该参数声明为implicit,这意味着编译器将在您调用构造函数的位置尝试在范围内查找合适的值。如果您将Ordering作为隐式值,则编译器将有资格获得此处理:

scala> implicit object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i}
defined module A

scala> val tm1 = new collection.immutable.TreeMap[A, String]()
tm1: scala.collection.immutable.TreeMap[A,String] = Map()

编辑:

该示例在REPL中起作用,因为REPL将您的代码包含在不可见的类定义中。这是一个独立的作品:

case class A(val i:Int) extends Ordered[A] { def compare(o:A) = i - o.i }

object A { implicit object AOrdering extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i } }

class B {
    import A.AOrdering

    val tm1 = new collection.immutable.TreeMap[A, String]()
}

答案 2 :(得分:5)

尝试扩展Ordering[A],而不是扩展Ordered[A]。像这样:

scala> case class A(val i:Int) extends Ordered[A] {def compare(o:A) = i-o.i}
defined class A

scala> A(1)<A(2)
res0: Boolean = true

scala> A(1)<A(0)
res1: Boolean = false

scala> new collection.immutable.TreeMap[A, String]()
res3: scala.collection.immutable.TreeMap[A,String] = Map()