Scala 2.8树映射和自定义排序
我正在从Scala2.7切换到Scala2.8并使用排序。它看起来很直截了当,但我想知道我是否可以让它少一点冗长。例如:Scala 2.8树映射和自定义排序,scala,scala-2.8,treemap,Scala,Scala 2.8,Treemap,我正在从Scala2.7切换到Scala2.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 如果我尝试创建一个树映射,我会得到一个错误 scala> new collec
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
如果我尝试创建一个树映射,我会得到一个错误
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]()
^
我是否总是必须明确指定顺序,还是有较短的格式
谢谢注意诊断中的“隐式”一词。该参数被声明为隐式
,这意味着编译器将在调用构造函数时尝试在作用域中找到合适的值。如果您将排序设置为隐式值,则编译器将对其进行以下处理:
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]()
}
不要扩展
Ordering[A]
,而是尝试扩展Ordering[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()
scala>case类A(val i:Int)扩展了有序[A]{def compare(o:A)=i-o.i}
定义的A类
scala>A(1)A(1)新集合。不可变。树映射[A,字符串]()
res3:scala.collection.immutable.TreeMap[A,String]=Map()
请注意,有一种稍微不太繁琐的方法来创建订单
:
implicit val OrderingA = Ordering.by((_: A).i)
订购的主要优点是,您可以为同一个类提供许多。如果您的A
类确实是有序的
,那么您应该扩展它。否则,您可以显式传递排序,而不是使用隐式:
new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))
如果我在代码中尝试这样做,我会被告知“错误:`implicit'修饰符不能用于顶级对象”。那么,有没有一种方法可以对顶级对象执行此操作?@Dave没有,但是对于包含
a
的包,您可以将这样一个隐式放置在包对象中@Daniel:您尝试过吗?我做了,但不知怎么被编译器拒绝了。我不知道我是做错了还是真的不允许。我没有尝试包对象解决方案。其余的都没问题。@Dave实际上,将隐式对象A排序
,而不是对象同伴(即对象A
)。这似乎也能起作用,其工作方式是低优先级隐式将树映射的有序[a]转换为有序[a]。不幸的是,我们序列化了用于存储的树映射,并且排序的类有点不稳定(一些$$anon$类)。警告:通过减去整数来比较整数不起作用。也适用于此处给出的大多数答案。。。如果整数很大,并且有相反的符号。由于符号切换,因此该数字可能溢出,产生相反的结果。但是如果你使用的数字接近Int.MAX\u值
,你已经在玩火了,不是吗?我认为减法“成语”在scala中特别简洁/有用,因为scala没有(三元)条件表达式(?:)@Kornbridge scala有条件表达式。语法为:if(condition)valueIfTrue else valueIfFalse。现在,如果使用符号?而且:不是“if(“and”)else”是一个要求,那么不,Scala没有条件表达式。看起来简洁、易懂、灵活。再次来到这里,想要投票/评论,但是。。我已经去过那里了!
new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))