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接口来完成排序的。

Scala集合排序的更多相关文章

  1. Scala集合操作

    大数据技术是数据的集合以及对数据集合的操作技术的统称,具体来说: 1.数据集合:会涉及数据的搜集.存储等,搜集会有很多技术,存储技术现在比较经典方案是使用Hadoop,不过也很多方案采用Kafka.  ...

  2. Scala集合常用方法解析

    Java 集合 : 数据的容器,可以在内部容纳数据  List : 有序,可重复的  Set : 无序,不可重复  Map : 无序,存储K-V键值对,key不可重复 scala 集合 : 可变集合( ...

  3. Scala集合笔记

    Scala的集合框架类比Java提供了更多的一些方便的api,使得使用scala编程时代码变得非常精简,尤其是在Spark中,很多功能都是由scala的这些api构成的,所以,了解这些方法的使用,将更 ...

  4. Scala集合(一)

    Scala集合的主要特质 Iterator,用来访问集合中所有元素 val coll = ... // 某种Iterable val iter = col.iterator while(iter.ha ...

  5. Scala集合类型详解

    Scala集合 Scala提供了一套很好的集合实现,提供了一些集合类型的抽象. Scala 集合分为可变的和不可变的集合. 可变集合可以在适当的地方被更新或扩展.这意味着你可以修改,添加,移除一个集合 ...

  6. Spark记录-Scala集合

    Scala列表 Scala列表与数组非常相似,列表的所有元素都具有相同的类型,但有两个重要的区别. 首先,列表是不可变的,列表的元素不能通过赋值来更改. 其次,列表表示一个链表,而数组是平的. 具有类 ...

  7. Java比较器对数组,集合排序一

    数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...

  8. ArrayList集合排序

    using System;using System.Collections;using System.Collections.Generic;using System.Text; namespace ...

  9. 【Java进阶】---map集合排序

    map集合排序         这篇文章讲的不仅仅是map排序,比如把对象按某一属性排序,它都可以解决这些问题.   比如,有N个对象,每个对象有个属性就是成绩,成绩分:优秀,良好,合格.那我们如何按 ...

  10. CopyOnWriteArrayList集合排序异常问题

    1.集合自定义排序实现 对List集合的自定义排序想必大家都知道要使用如下的方式,通过实现Comparator接口并实现compare方法来实现. /** * * @方法名 changeChain * ...

随机推荐

  1. 软件设计原则(Principles)

    设计模式的从许多优秀的软件中总结出来的 , 使用设计模式能够实现可复用.可维护.开发人员之间方便沟通设计和理解代码. Tips 对于模式的使用 , 不能拘泥于格式 , 事实上根据需要模式是可以演化的 ...

  2. (五) Mysql 之锁详细篇

    一.锁的分类1.范围:全局锁.表级锁.行级锁2.功能分类:共享锁.排它锁 二.数据库的全局锁 加锁:mysql> flush tables with read lock; 释放锁:mysql&g ...

  3. channel 死锁

    死锁: - 单个协程永久阻塞 - 两个或两个以上的协程执行过程中,由于竞争资源或由于彼此通信而造成的一种阻塞的现象. channel 死锁场景: - 非缓存channel只写不读 - 非缓存chann ...

  4. Qt5 CMake项目简单模板

    cmake_minimum_required(VERSION 3.5) project(test VERSION 0.1 LANGUAGES CXX) set(CMAKE_INCLUDE_CURREN ...

  5. [UnityShader]unity中2D Sprite显示阴影和接受阴影

    首先是效果 要让2D显示阴影,首先假设知道Unity阴影来源(shader中的ShadowCaster) 最简单的方法是,首先从官网下载Sprite-Default.Shader,查看源码 然后复制粘 ...

  6. TensorFlow的基础结构

    Tensorflow 是非常重视结构的, 我们得建立好了神经网络的结构, 才能将数字放进去, 运行这个结构. 这个例子简单的阐述了 tensorflow 当中如何用代码来运行我们搭建的结构. 创建数据 ...

  7. macOS 系统安装提示应用程序副本已损坏的解决方法

    错误预览: 操作方法,关闭Wi-Fi,网线(以修改时间为 2020 为例): 再次尝试安装吧...

  8. 《Toward Fast, Flexible, and Robust Low-Light Image Enhancement》

    1.(23条消息) 图像增强评价标准EME和matlab代码_eme指标_zhonglingyuxiuYYX的博客-CSDN博客 2.nn.moduleList 3.LOE:lightness ord ...

  9. 靶场练习2:cloudantvirus

    靶场链接 https://www.vulnhub.com/entry/boredhackerblog-cloud-av,453/ 信息收集 练习1用了arp-scan,这种工具有可能会被防火墙流量监测 ...

  10. redisTemplate类学习及理解

    List<Object> list = masterRedisTemplate.executePipelined((RedisCallback<Long>) connectio ...