目前,我正在学习 Scala,现在,我对比较对象的有序特征有些困惑。
考虑下面的例子,这是我目前对比较的理解,
Case I,
class Example(var n: Int) extends Ordered[Example] {
// ...
def compare(that: Example) =
(this.n) - (that.n)
}
var obj1 = new Example(12)
var obj2 = new Example(12)
obj1 compare obj2 //return 0 i.e. obj1 and obj2 are equal.
Case II,
class Example(var m: Int, var n: Int) extends Ordered[Example] {
// ...
def compare(that: Example) =
(this.m * this.n) - (that.m * that.n)
}
var obj1 = new Example(1, 2)
var obj2 = new Example(1, 2)
obj1 compare obj2 //return 0 i.e. obj1 and obj2 are equal.
Case III,
class Example(var name: String) extends Ordered[Example] {
// ...
def compare(that: Example) =
this.name compare that.name
}
var obj1 = new Example("abc")
var obj2 = new Example("abc)
obj1 compare obj2 //return 0 i.e. obj1 and obj2 are equal.
Case IV,
class Example(var name1: String, var name2: String) extends Ordered[Example] {
// ...
def compare(that: Example) =
(this.name1 + this.name2) compare (that.name1+that.name2)
}
var obj1 = new Example("abc","def")
var obj2 = new Example("abc","def")
obj1 compare obj2 //return 0 i.e. obj1 and obj2 are equal.
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是,如果类中存在非构造函数字段怎么办?例如,
class Example(var n: Int) extends Ordered[Example] {
var someVar: String = "default";
// ...
def compare(that: Example) =
(this.n) - (that.n)
//do we also need to compare someVar???? otherwise, object will have different state right??
}
var obj1 = new Example(12)
obj1.someVar = "value 1"
var obj2 = new Example(12)
obj2.someVar = "another value 2"
obj1 compare obj2 //Again, return 0 i.e. obj1 and obj2 are equal.
Run Code Online (Sandbox Code Playgroud)
以上理解如有错误,请指正。
在您的比较方法中,您仅比较n
实例的值。n
因此,具有相同和不同的实例someVar
将被认为是相似的。为了基于两者进行比较n
,并在比较方法中someVar
考虑n
值和值。someVar
这是如何执行此操作的代码
class Example(var n: Int) extends Ordered[Example] {
var someVar: String = "default"
def compare(that: Example) = {
(this.n) - (that.n) match {
case 0 => this.someVar.compare(that.someVar)
case other => other
}
}
}
Run Code Online (Sandbox Code Playgroud)
当不同示例的 之间存在联系时,n
回退到字符串比较。您所要做的只是调用compare
字符串实例。
如果主字段相等,则回退到比较次要字段,依此类推,直到用完要比较的字段。
更惯用的比较方式
class Example(var n: Int) extends Ordered[Example] {
var someVar: String = "default"
import scala.math.Ordered.orderingToOrdered
def compare(that: Example) = (this.n, this.someVar) compare (that.n, that.someVar)
}
Run Code Online (Sandbox Code Playgroud)
创建元组并对元组调用比较,不要忘记import scala.math.Ordered.orderingToOrdered
。
一般信息
compare
返回零或 +ve 或 -ve 整数。通过这种方式,算法可以计算出实现排序特征的对象集合的排序。当比较扩展 Ordered 特征并基于比较方法返回的整数的两个实例时,算法可能知道在排序或排序时应首先放置特定类型的哪个实例。这在用于排序的 Scala 集合中非常常见。
Scala REPL
注意比较方法
scala> case class A(a: Int) extends AnyVal with Ordered[A] { override def compare(that: A): Int = this.a - that.a }
defined class A
Run Code Online (Sandbox Code Playgroud)
请注意排序顺序,即升序。
scala> List(A(1), A(2)).sorted
res4: List[A] = List(A(1), A(2))
Run Code Online (Sandbox Code Playgroud)
现在,我在减去后返回结果的负数,注意顺序现在将颠倒过来。
scala> case class A(a: Int) extends AnyVal with Ordered[A] { override def compare(that: A): Int = - (this.a - that.a) }
defined class A
Run Code Online (Sandbox Code Playgroud)
注意顺序颠倒了
scala> List(A(1), A(2)).sorted
res5: List[A] = List(A(2), A(1))
Run Code Online (Sandbox Code Playgroud)
请注意,如果比较返回 0,并不意味着对象相等。当对象不相等时,可以在compare方法中返回0,以在排序或排序时给予相同的优先级。