2016-11-30 24 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”。 –