你想要對一個集合元素進行排序。或者你想定義一個自定義類來實現Ordered trait,來讓你可使用sorted方法,或者使用比較操符<,<=,>,>=來對類的實例進行比較。算法
你可使用sorted或者sortWith方法來對集合進行排序。app
Sorted方法能夠對集合元素類型爲Double,Float,Int和其餘能夠隱試轉化scala.math.Ordering的進行排序。ide
scala> val l = List(10, 5, 8, 1, 7).sorted l: List[Int] = List(1, 5, 7, 8, 10) scala> val b = List("banana", "pear", "apple", "orange").sorted b: List[String] = List(apple, banana, orange, pear)
Rich版本的numeric類(好比RichInt)和StringOps類都實現了Ordered trait,因此他們可使用sorted方法實現排序。this
SortWith方法讓你可使用本身的排序邏輯來實現排序規則。下面的例子展現瞭如何對集合元素類型爲Int和String使用sortWith排序:spa
scala> List(10, 5, 8, 1, 7).sortWith(_ < _) res14: List[Int] = List(1, 5, 7, 8, 10) scala> List(10, 5, 8, 1, 7).sortWith(_ > _) res15: List[Int] = List(10, 8, 7, 5, 1) scala> List("banana", "pear", "apple", "orange").sortWith(_ < _) res16: List[String] = List(apple, banana, orange, pear) scala> List("banana", "pear", "apple", "orange").sortWith(_ > _) res17: List[String] = List(pear, orange, banana, apple)
你的排序方法的複雜度取決於你的排序需求。舉個例子,你能夠經過sort訪問元素的方法,好比下面這個例子,按長度對一個字符串集合進行排序:scala
scala> List("banana", "pear", "apple", "orange").sortWith(_.length < _.length) res18: List[String] = List(pear, apple, banana, orange) scala> List("banana", "pear", "apple", "orange").sortWith(_.length > _.length) res19: List[String] = List(banana, orange, apple, pear)
若是你的排序方法很是複雜或者會被重複使用,那麼你能夠先定義這個方法後,再調用此方法:excel
scala> def sortByLength(s1: String, s2: String) = { | println("compare %s and %s".format(s1, s2)) | s1.length > s2.length | } sortByLength: (s1: String, s2: String)Boolean scala> List("banana", "pear", "apple").sortWith(sortByLength) compare pear and banana compare banana and pear compare apple and pear compare apple and pear compare apple and banana compare banana and apple res20: List[String] = List(banana, apple, pear)
若是你定義的類,沒有定義對Ordering的隱式轉換,那麼你就沒有辦法經過調用sorted方法來對集合元素進行排序。code
scala> class Person(var name: String) { | override def toString = name | } defined class Person
建立一個Person集合:orm
scala> val ty = new Person("Tyler") ty: Person = Tyler scala> val al = new Person("Al") al: Person = Al scala> val paul = new Person("Paul") paul: Person = Paul scala> val dudes = List(ty, al, paul) dudes: List[Person] = List(Tyler, Al, Paul)
若是你調用sorted方法對dudes進行排序,那麼你會看到下面的錯誤提示:對象
scala> dudes.sorted <console>:13: error: No implicit Ordering defined for Person. dudes.sorted ^
可是你可使用sortWith對dudes進行排序:
scala> dudes.sortWith(_.name < _.name) res1: List[Person] = List(Al, Paul, Tyler) scala> dudes.sortWith(_.name > _.name) res2: List[Person] = List(Tyler, Paul, Al)
混入Ordered特質可以讓你的程序使用sorted方法來對Person集合進行排序,可是你必須實現compare方法。
class Person(var name: String) extends Ordered[Person]{ override def toString = name override def compare(that: Person): Int = { if (this.name == that.name) return 0 else if (this.name > that.name) return 1 else return -1 } }
這個新的Person類就可使用sorted方法來進行排序了。
Compare方法提供了排序功能,compare方法會這樣進行工做:
若是兩個對象相等,返回0
若是this<that那麼返回一個負數
若是shit>that那麼返回一個正數
類的兩個實例誰大誰小徹底取決於你的compare算法,由於目前這個算法僅僅比較兩個字符串的值,因此也能夠寫成這樣:
def compare (that: Person) = this.name.compare(that.name)
使用Ordered特質的另一個好處是它可讓你在代碼中直接比較對象實例。
if (al > ty) println("Al") else println("Tyler")
上面代碼之因此能夠工做是由於Ordered特質實現了<=, <, >, >=方法,並調用你定義的compare方法來使之生效。
For more information, the Ordered and Ordering Scaladoc is excellent, with good examples of this approach, and other approaches.
• The Ordering trait
• The Ordered trait