scala中sorted,sortby,sortwith的用法(轉)
阿新 • • 發佈:2018-12-22
scala中sorted,sortWith,sortBy用法詳解
2017年07月23日 23:07:51 bitcarmanlee 閱讀數:9249
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/bitcarmanlee/article/details/75949268
scala的集合中提供了三種排序的方式:sorted,sortWith,sortBy。那麼這三種方式有什麼不同呢?下面我們結合原始碼來分析一下
1.sorted
先來看看scala中sorted的原始碼。
def sorted[B >: A](implicit ord: Ordering[B]): Repr = { val len = this.length val arr = new ArraySeq[A](len) var i = 0 for (x <- this.seq) { arr(i) = x i += 1 } java.util.Arrays.sort(arr.array, ord.asInstanceOf[Ordering[Object]]) val b = newBuilder b.sizeHint(len) for (x <- arr) b += x b.result }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
原始碼中有兩點值得注意的地方:
1.sorted方法中有個隱式引數ord: Ordering。
2.sorted方法真正排序的邏輯是呼叫的java.util.Arrays.sort。
2.sortBy
看看sortBy的原始碼,很簡單。
def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr = sorted(ord on f)
- 1
sortBy最後也是呼叫的sorted方法。不一樣的地方在於,sortBy前面還需要提供一個屬性。
3.sortWith
sortWith的原始碼如下。
def sortWith(lt: (A, A) => Boolean): Repr = sorted(Ordering fromLessThan lt)
- 1
跟前面兩個不同的是,sortWith需要傳入一個比較函式用來比較!
4.例項
理論部分說完了,下面來乾貨
object ImplicitValue { implicit val KeyOrdering = new Ordering[String] { override def compare(x: String, y: String) : Int = { y.compareTo(x) } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
首先定義了一個隱式比較器。
def test1() = {
import ImplicitValue.KeyOrdering
val list = List( "a", "g", "F", "B", "c")
val sortedList = list.sorted
println(sortedList) // List(g, c, a, F, B)
}
- 1
- 2
- 3
- 4
- 5
- 6
注意因為我們將隱式比較器import了進來,這個時候sorted排序的規則是按照我們自定義的比較器進行比較。在我們自定義的比較器中,定義的是按字串逆序,所以最終的輸出結果為字串按從大到小的順序排列!
再來看看sortWith的用法。
//忽略大小寫排序
def compareIngoreUpperCase(e1: String, e2: String) : Boolean = {
e1.toLowerCase < e2.toLowerCase
}
def test2() = {
val list = List( "a", "g", "F", "B", "c")
val sortWithList1 = list.sortWith(_ < _) // List(B, F, a, c, g)
val sortwithList2 = list.sortWith((left, right) => left < right) //List(B, F, a, c, g)
val sortwithList3 = list.sortWith(compareIngoreUpperCase) // List(a, B, c, F, g)
println(sortWithList1)
println(sortwithList2)
println(sortwithList3)
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
本例中, sortWithList1與sortWithList2最終的結果是一致的,只不過寫法不一樣而已,都是按字串從小到大的順序排列。sortwithList3則是按照傳入的compareIngoreUpperCase函式進行排序!
最後看看sortBy的程式碼
def test3() = {
val m = Map(
-2 -> 5,
2 -> 6,
5 -> 9,
1 -> 2,
0 -> -16,
-1 -> -4
)
//按key排序
m.toList.sorted.foreach{
case (key, value) =>
println(key + ":" + value)
}
println
//按value排序
m.toList.sortBy(_._2).foreach {
case (key, value) =>
println(key + ":" + value)
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
最後的輸出結果為:
-2:5
-1:-4
0:-16
1:2
2:6
5:9
0:-16
-1:-4
1:2
-2:5
2:6
5:9