問題導讀
1.map能否直接排序?
2.如何轉換,才能排序?
3.排序結果可以存儲在哪兩個集合中?
4._*如何使用?
5.排序函數中,哪個可以進行升序和降序排列?
6.他們的排序性能如何?
如過想要對一個map排序,該如何實現。
首先給一個不可變的map
?
1 2 3 4 5 6 7 |
scala> val grades = Map( "Kim" -> 90 , | "Al" -> 85 , | "Melissa" -> 95 , | "Emily" -> 91 , | "Hannah" -> 92 | ) grades : scala.collection.immutable.Map[String,Int] = Map(Hannah -> 92 , Melissa -> 95 , Kim -> 90 , Emily -> 91 , Al -> 85 ) |
你可以按照value排序,從高到低,使用sortBy
?
1 2 3 4 5 |
scala> import scala.collection.immutable.ListMap import scala.collection.immutable.ListMap scala> ListMap(grades.toSeq.sortBy( _ . _ 2 ) :_ *) res 0 : scala.collection.immutable.ListMap[String,Int] = Map(Al -> 85 , Emily -> 91 , Hannah -> 92 , Kim -> 90 , Melissa -> 95 ) |
當然你也可以按照名字排序,也就是key排序,但是key排序顯然作用不大。
?
1 |
scala> ListMap(grades.toSeq.sortBy( _ . _ 1 ) :_ *) |
上面是使用sortBy,下面我們使用sortWith
從低到高排序
?
1 2 3 |
scala> ListMap(grades.toSeq.sortWith( _ . _ 2 < _ . _ 2 ) :_ *) res 2 : scala.collection.immutable.ListMap[String,Int] = Map(Al -> 85 , kim -> 90 , Emily -> 91 , Hannah -> 92 , Melissa -> 95 ) |
從高到低排序
?
1 2 3 |
scala> ListMap(grades.toSeq.sortWith( _ . _ 2 > _ . _ 2 ) :_ *) res 3 : scala.collection.immutable.ListMap[String,Int] = Map(Melissa -> 95 , Hannah -> 92 , Emily -> 91 , kim -> 90 , Al -> 85 ) |
上面所有的例子,都不是使用map直接排序,而是使用sort函數,結果在一個新的已經排序的map中,輸出結果需要一個新的變量。
因此你可以使用ListMap 或則LinkedHashMap ,下面使用的是LinkedHashMap .
?
01 02 03 04 05 06 07 08 09 10 |
scala> val x = collection.mutable.LinkedHashMap(grades.toSeq.sortBy( _ . _ 2 ) :_ *) x : scala.collection.mutable.LinkedHashMap[String,Int] = Map(Al -> 85 , kim -> 90 , Emily -> 91 , Hannah -> 92 , Melissa -> 95 ) scala> x.foreach(println) (Al, 85 ) (kim, 90 ) (Emily, 91 ) (Hannah, 92 ) (Melissa, 95 ) |
討論與思考:
對於一個map
?
1 2 3 4 5 6 7 |
scala> val grades = Map( "Kim" -> 90 , | "Al" -> 85 , | "Melissa" -> 95 , | "Emily" -> 91 , | "Hannah" -> 92 | ) grades : scala.collection.immutable.Map[String,Int] = Map(Hannah -> 92 , Melissa -> 95 , Kim -> 90 , Emily -> 91 , Al -> 85 ) |
我們爲什麼要把他轉換爲序列toSeq
?
1 |
grades.toSeq |
因爲map沒有排序函數,所以我們轉換序列後,可以使用排序函數
?
1 |
grades.toSeq.sortBy( _ . _ 2 ) |
?
1 |
grades.toSeq.sortWith( _ . _ 2 < _ . _ 2 ) |
數據排序後,會存儲在ListMap 中
?
1 |
ListMap(grades.toSeq.sortBy( _ . _ 2 ) :_ *) |
LinkedHashMap 也存儲排序後的數據,如下
?
1 |
import scala.collection.mutable.LinkedHashMap |
?
1 |
LinkedHashMap(grades.toSeq.sortBy( _ . _ 2 ) :_ *) |
有可變和不可變的listMap版本,LinkedHashMap 只是一個可變的類,是比較好的解決方案。
關於排序函數中 _*的含義
整體來說,他可以代表多個參數,詳細可參考下面說明
_*他可以傳遞或則代表多個參數,比如 ListMap 或則LinkedHashMap. 你不能直接初始化ListMap 使用tuples序列,但是apply 方法在伴生對象接受Tuple2 變參數,可以使用x和它一起,如下面例子
?
1 |
scala> ListMap(x : _ *) |
嘗試創建ListMap不使用上面方式
?
1 |
ListMap(x) |
另外一種方式, 自定義函數,使用可變參數,_*它是如何使用的。下面printAll ,需要一個參數,和一個可變參數的String類型。
?
1 2 3 |
def printAll(strings : String*) { strings.foreach(println) } |
你可以創建list如下
上面我們使用printAll(fruits)出錯,我們可以這樣使用
?
1 |
printAll(fruits : _ *) |
排序性能
額外補充他們的排序性.這裏就不在過多說明,可參考下圖