轉:Scala的map實現key和value排序及各種排序比較等知識討論

問題導讀

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 : _ *)

排序性能

額外補充他們的排序性.這裏就不在過多說明,可參考下圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章