2016-11-30 6 views
0

現在、私はScalaを学習していますが、今は、オブジェクトを比較するためにOrdered 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. 

だから、私の質問で、どのような非コンストラクタフィールドがクラスに存在する場合は?たとえば、

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のインスタンスは類似していると見なされます。 nsomeVarの両方に基づいて比較を行うには、比較方法でn値とsomeVarの両方を考慮に入れてください。ここで

は異なる例のsが文字列の比較にフォールバック n」の間のタイがある場合は、この

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

を行う方法のコードです。あなたがしなければならないことは、ストリングインスタンスに対してcompareと呼ぶだけです。

比較するフィールドがなくなるまで、プライマリフィールドが等しければ2次フィールドの比較にフォールバックします。タプルを作成し、タプルに比較呼び出し、import scala.math.Ordered.orderingToOrderedに忘れてはいけません。

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

を比較する

より慣用的な方法

一般情報

compareリターンゼロまたは+ VEの又は-ve整数。このようにしてアルゴリズムは、順序付け特性を実装するオブジェクトの集合の順序を把握することができる。 Ordered traitを拡張する2つのインスタンスを比較し、compareメソッドによって返された整数に基づいて、アルゴリズムは、特定の型のどのインスタンスが順序付けまたはソート中に最初に配置されるべきかを知ることがあります。これは、並べ替えの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)) 

今、私は結果を否定した後に返信し、通知の順序は今や逆になります。順

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

比較戻り0の場合オブジェクトが等しいことを意味しないことに注意を逆

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

注意。順序付けやソート中にオブジェクトが等しい優先度を持たない場合は、compareメソッド内で0を返すことができます。

+0

ありがとう、私はこれが大きな説明だと言わなければなりません。あなたの答えは本当に私に多くの理解を助けました[[]特性と私は多くの新しい概念を学びました。 "scala.math.Ordered.orderingToOrdered" –

関連する問題