Understanding Scala Ordered[ ] trait 比较参考

Understanding Scala Ordered[ ] trait to compare reference

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

所以,我的问题是,如果 class 中有非构造函数字段怎么办?例如,

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.

以上理解有误请指正

在您的比较方法中,您只比较实例的 n 值。因此,具有相同 n 和不同 someVar 的实例将被视为相似。为了根据 nsomeVar 进行比较,请在比较方法中同时考虑 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
    }
  }
}

n 的不同示例之间存在平局时,回退到字符串比较。您所要做的就是在字符串实例上调用 compare

Fallback to comparison of secondary fields if primary fields are equal and so on till you run out of fields to 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) 
 }

创建元组并在元组上调用比较,不要忘记import scala.math.Ordered.orderingToOrdered

一般信息

compare returns 零或 +ve 或 -ve 整数。通过这种方式,算法可以计算出实现排序特征的对象集合的排序。当比较两个扩展 Ordered 特征并基于比较方法的整数 return 的实例时,算法可能知道在排序时应该首先放置特定类型的哪个实例,或者 sorting.This 在用于排序的 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

注意排序顺序,它的升序。

scala> List(A(1), A(2)).sorted
res4: List[A] = List(A(1), A(2))

现在,我return对减法后的结果求反,通知顺序现在颠倒了。

scala> case class A(a: Int) extends AnyVal  with Ordered[A] { override def compare(that: A): Int =  - (this.a - that.a) }
defined class A

注意顺序颠倒了

scala> List(A(1), A(2)).sorted
res5: List[A] = List(A(2), A(1))

Notice that if compare returns 0 that does not mean that objects are equal. You can return 0 inside compare method when objects are not equal to give equal priority while ordering or sorting.