簡體   English   中英

了解Scala Ordered []特性以比較參考

[英]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 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.

如果以上理解有誤,請糾正我。

在您的compare方法中,您僅比較實例的n值。 因此,具有相同n和不同someVar的實例將被視為相似。 為了基於nsomeVar進行比較,在compare方法中要同時考慮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

如果主要字段相等,則退回到比較輔助字段,依此類推,直到用盡所有要比較的字段為止。

比較的慣用方式

 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返回零或+ ve或-ve整數。 這樣,算法可以找出實現排序特征的對象集合的排序。 當比較兩個擴展有序特征並基於compare方法返回的整數的實例時,算法可能會知道在排序或排序時應將特定類型的哪個實例放在首位,這在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))

現在,我將減去后的結果取反,現在通知順序將顛倒。

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))

請注意,如果compare返回0,則並不意味着對象相等。 當對象不相等時,可以在compare方法內部返回0,以便在排序或排序時給予相同的優先級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM