Scala集合排序有三种方法:sorted、sortBy()、sortWith()

(1)sorted

对一个集合进行自然排序,通过传递隐式的Ordering
源码中有两点值得注意的地方:
1.sorted方法中有个隐式参数ord: Ordering。
2.sorted方法真正排序的逻辑是调用的java.util.Arrays.sort。

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
}

(2)sortBy

对一个属性或多个属性进行排序,通过它的类型。
sortBy最后也是调用的sorted方法。不一样的地方在于,sortBy前面还需要提供一个属性。

def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr = sorted(ord on f)

(3)sortWith

基于函数的排序,通过一个comparator函数,实现自定义排序的逻辑

def sortWith(lt: (A, A) => Boolean): Repr = sorted(Ordering fromLessThan lt)

例子一:基于单集合单字段的排序

   val xs=Seq(1,5,3,4,6,2)
println("==============sorted排序=================")
println(xs.sorted) //升序
println(xs.sorted.reverse) //降序
println("==============sortBy排序=================")
println( xs.sortBy(d=>d) ) //升序
println( xs.sortBy(d=>d).reverse ) //降序
println("==============sortWith排序=================")
println( xs.sortWith(_<_) )//升序
println( xs.sortWith(_>_) )//降序

例子二:基于元组多字段的排序

注意多字段的排序,使用sorted比较麻烦,这里给出使用sortBy和sortWith的例子

先看基于sortBy的实现:

val pairs = Array(
("a", 5, 1),
("c", 3, 1),
("b", 1, 3)
) //按第三个字段升序,第一个字段降序,注意,排序的字段必须和后面的tuple对应
val bx= pairs.
sortBy(r => (r._3, r._1))( Ordering.Tuple2(Ordering.Int, Ordering.String.reverse) )
//打印结果
bx.map( println )

再看基于sortWith的实现:

val pairs = Array(
("a", 5, 1),
("c", 3, 1),
("b", 1, 3)
)
val b= pairs.sortWith{
case (a,b)=>{
if(a._3==b._3) {//如果第三个字段相等,就按第一个字段降序
a._1>b._1
}else{
a._3<b._3 //否则第三个字段升序
}
}
}
//打印结果
b.map(println)

例子三:基于类的排序

先看sortBy的实现方法 排序规则:先按年龄排序,如果一样,就按照名称降序排

case class Person(val name:String,val age:Int)

    val p1=Person("cat",23)
val p2=Person("dog",23)
val p3=Person("andy",25) val pairs = Array(p1,p2,p3) //先按年龄排序,如果一样,就按照名称降序排
val bx= pairs.sortBy(person => (person.age, person.name))( Ordering.Tuple2(Ordering.Int, Ordering.String.reverse) ) bx.map(
println
)

再看sortWith的实现方法:

case class Person(val name:String,val age:Int)

    val p1=Person("cat",23)
val p2=Person("dog",23)
val p3=Person("andy",25) val pairs = Array(p1,p2,p3) val b=pairs.sortWith{
case (person1,person2)=>{
person1.age==person2.age match {
case true=> person1.name>person2.name //年龄一样,按名字降序排
case false=>person1.age<person2.age //否则按年龄升序排
}
}
}
b.map(
println
)

例子四:对单集合自定义快速排序方法:

  def quickSort(a: List[Int]):List[Int]={
if (a.length < 2) a
else quickSort(a.filter(_ < a.head)) ++ a.filter(_ == a.head) ++ quickSort(a.filter(_ > a.head))
}
println(quickSort(List(1,3,2,9,5,7)))

总结:

本篇介绍了scala里面的三种排序函数,都有其各自的应用场景:

sorted:适合单集合的升降序

sortBy:适合对单个或多个属性的排序,代码量比较少,推荐使用这种

sortWith:适合定制化场景比较高的排序规则,比较灵活,也能支持单个或多个属性的排序,但代码量稍多,内部实际是通过java里面的Comparator接口来完成排序的。

最新文章

  1. (第九天)DOM事件
  2. mount -t nfs 的使用
  3. json_encode中文unicode的问题
  4. Python2.5-原理之模块
  5. Mybatis 开启事务@Transactional
  6. C++嵌入Python,以及两者混用
  7. JAVa中进制之间的转化方法
  8. 3DES封装类
  9. javascript-几个基础的排序算法
  10. linux 下 ifcfg-ethx配置和解析
  11. 二十六、Linux 进程与信号---system 函数 和进程状态切换
  12. Python常用的软件包
  13. SLICK基础
  14. 02: pycharm远程linux开发和调试代码
  15. idea的激活
  16. screen命令记录
  17. SWF运行时判断两个DisplayObject是否同个类型,属于flash professional库中的同一个元件
  18. RF-字符串转为整数的方法
  19. RR和RC复合语句加锁
  20. react 使用map 的时候提示 没有返回值

热门文章

  1. JZOJ 2020.07.27【NOIP提高组】模拟
  2. JZOJ 5354. 【NOIP2017提高A组模拟9.9】导弹拦截
  3. 精华推荐 |【算法数据结构专题】「延时队列算法」史上非常详细分析和介绍如何通过时间轮(TimingWheel)实现延时队列的原理指南
  4. mysql的七种基本关联查询方式
  5. Jmeter 快速生成测试报告
  6. appsettings.json用机密替换字符串-利用 VisualStudio 管理用户机密
  7. ASP.net EF动态映射实体
  8. 【C学习笔记】day4-2 求出0~999之间的所有“水仙花数”并输出。
  9. Mongo 常用命令
  10. v-if和v-show最重要一点