2016-11-30 22 views
0

目前,我正在學習Scala,現在,我有一些混淆理解Ordered特徵來比較對象。瞭解Scala Ordered []特徵來比較參考

考慮下面的例子,這是我目前比較瞭解,

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. 

請糾正我,如果上面的理解是錯誤的。

+0

'_ compare _ == 0'並不意味着元素相等,只是您使用的比較函數返回了'0'。如果您想要比較來驗證訂單的常規法則,則必須按照這樣的原則執行。 –

回答

4

在您的比較方法中,您只比較實例的n值。因此,具有相同n和不同someVar的實例將被視爲相似。爲了在比較方法中同時考慮基於nsomeVarn值和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的整數。這樣算法就可以計算實現排序特徵的對象集合的排序。當比較兩個擴展Ordered trait並基於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)) 

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

+0

非常感謝,我必須說這是一個很好的解釋。你的回答確實幫助我理解了Ordered []特質,並學習了許多新概念,例如「scala.math.Ordered.orderingToOrdered」。 –