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

排序性能

额外补充他们的排序性.这里就不在过多说明,可参考下图

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值