了解 Scala Ordered[ ] 特征以比较参考

Ra *_* Ka 0 scala traits

目前,我正在学习 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)

以上理解如有错误,请指正。

pam*_*amu 5

在您的比较方法中,您仅比较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,以在排序或排序时给予相同的优先级。