总概述

(1)sorted

对一个集合进行自然排序,通过传递隐式的Ordering

(2)sortBy

对一个属性或多个属性进行排序,通过它的类型。

(3)sortWith

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

sorted

概念

  1. 排序很重要,将来在大数据里面做计算,无非就是各种的指标,按照指定业务进行top3或者top10排序啥的.只要求前几的,一定是排序操作.

scala:
不管是可变集合还是不可变集合, 都是返回一个新的排好的序集合
原集合不动
sorted
默认都是自然排序(升序)

  1. 让排序的类型有自己排序的功能
    Ordered 就是java中的 Comparable
  2. 找一个第3方的比较器
    Ordering 就是java中的 Comparator

数值类型排序

val list1 = List(30, 50, 70, 60, 10, 20)
println(list1) //输出:List(30, 50, 70, 60, 10, 20)
// 排序操作,默认升序
println(list1.sorted) //输出: List(10, 20, 30, 50, 60, 70)
// 降序操作 reverse
println(list1.sorted.reverse) // 输出: List(70, 60, 50, 30, 20, 10)

对象类型依据某个字段的值进行排序

方式1,对象继承Ordered

这种方式不灵活,几乎是不用的.

因为比较器直接是在User类里面写死的,那么排序方式就只能一种了,如果想另外一种排序方式的话,就需要修改代码很不灵活

class User(val age: Int, val name: String) extends Ordered[User] {

  override def toString: String = s"[age = $age, name = $name]"

  override def compare(that: User): Int = this.age - that.age
}

object Sort1 {
  def main(args: Array[String]): Unit = {
    val user1 = new User(10, "a")
    val user2 = new User(20, "a")
    println(user1 < user2) // 输出: true
    println(user1 <= user2) // 输出: true
    println(user1 > user2) // 输出: false
  }

方式2 用比较器的方式

这种方式更灵活,想按什么方式排序就提供对应的比较器.这种方式是主流的,用的比较多.

class User(val age: Int, val name: String) {
  override def toString: String = s"[age = $age, name = $name]"
}

object Sort1 {
  def main(args: Array[String]): Unit = {
    val user1 = new User(10, "a")
    val user2 = new User(20, "a")
    val user3 = new User(30, "a")
    val user4 = new User(40, "a")
    // 顺序是乱的
    val value = List[User](user1, user3, user2, user4)
    println(value) //输出: List([age = 10, name = a], [age = 30, name = a], [age = 20, name = a], [age = 40, name = a])
    //降序排序
    val value1 = value.sorted(new Ordering[User] {
      override def compare(x: User, y: User): Int = x.age - y.age
    }.reverse)
    println(value1) //输出:  List([age = 40, name = a], [age = 30, name = a], [age = 20, name = a], [age = 10, name = a])

  }
}

sortBy

不需要提供任何的逻辑代码, 只需要指定要排序的指标.

数值类型排序

    val list1 = List(30, 50, 70, 60, 10, 20)
    //安装返回的指标排序
    val list2: List[Int] = list1.sortBy(x => x)(Ordering.Int.reverse)
    println(list2) //输出: List(70, 60, 50, 30, 20, 10)

字符串类型排序

单条件排序

默认按照字符串的字符表排序,就是 abcdefg…..

    val list3 = List("zzzzz", "hello", "world", "hello", "aaa", "b")
    val list4: List[String] = list3.sortBy(x => x)
    println(list4) //输出: List(aaa, b, hello, hello, world, zzzzz)

按照字符串长度升序排序

    val list2 = list1.sortBy(x => x.length)(Ordering.Int)
    println(list2) //输出: List(b, aaa, zzzzz, hello, world, hello)
    //下面两个效果是一样的
    val list3 = list1.sortBy(x => x.length)
    val list4 = list1.sortBy(_.length)

按照字符串长度降序排序

    val list2 = list1.sortBy(x => x.length)(Ordering.Int.reverse)
    println(list2) //输出: List(zzzzz, hello, world, hello, aaa, b)
    //下面两个效果是一样的
    val list3 = list1.sortBy(x => -x.length)
    val list4 = list1.sortBy(-_.length)

多条件排序

如果是多个条件指标, 就把这多个指标放在元组中返回,但是前提是最多只有九个条件指标,如果超过九个条件指标的话,就不行了,不过一般情况下真实业务场景估计也不会出现排个顺序要根据超过9个指标来排序的.

需要注意,在编写多条件的时候,(Ordering.Tuple2(Ordering.Int.reverse, Ordering.String)) 代码一定不要换号,如果换行可能就会出现编译不过去的情况了.

先按照长度升序排, 长度相等的时候使用字母表的升序排

    val list1 = List("zzzzz", "hello", "world", "hello", "aaa", "b")
    val list2 = list1.sortBy(x => (x.length, x))
    println(list2) //输出: List(b, aaa, hello, hello, world, zzzzz)

先按照长度降序排, 长度相等的时候使用字母表的升序排

    val list1 = List("zzzzz", "hello", "world", "hello", "aaa", "b")
    val list3 = list1.sortBy(x => (x.length, x))(Ordering.Tuple2(Ordering.Int.reverse, Ordering.String))
    println(list3) //输出:List(hello, hello, world, zzzzz, aaa, b)

先按照长度升序, 长度相等的时候使用字母表的降序

    val list1 = List("zzzzz", "hello", "world", "hello", "aaa", "b")
    val list2 = list1.sortBy(x => (x.length, x))(Ordering.Tuple2(Ordering.Int, Ordering.String.reverse))
    println(list2) //输出: List(b, aaa, zzzzz, world, hello, hello)

对象类型排序

按照对象里面多个值进行排序

class Person(val age: Int, val name: String) {
  override def toString: String = s"[age =$age , name =$name ]"
}

object Sort2 {
  def main(args: Array[String]): Unit = {


    val list = List(new Person(10, "a"),
      new Person(30, "d"),
      new Person(10, "b"),
      new Person(8, "c"))
    // 年龄升序,如果年龄相等,再按照姓名升序
    val list2 = list.sortBy(user => (user.age, user.name))
    println(list2) //输出: List([age =8 , name =c ], [age =10 , name =a ], [age =10 , name =b ], [age =30 , name =d ])
    // 年龄升序,如果年龄相等,再按照姓名降序
    val list3 = list.sortBy(user => (user.age, user.name))(Ordering.Tuple2(Ordering.Int, Ordering.String.reverse))
    println(list3) //输出:  List([age =8 , name =c ], [age =10 , name =b ], [age =10 , name =a ], [age =30 , name =d ])
  }
}

sortWith

这种方式如果是根据对象排序的话就得写复杂的函数了,很不好.

    val list1 = List(30, 50, 70, 60, 10, 20)
    // 升序排序 , x 是不是小于y , 表达式 x < y 如果是true就是x就在前面y就在后面,那么就是升序,否则就是降序
    val list2: List[Int] = list1.sortWith((x, y) => x < y)
    // 简写:
    val list3: List[Int] = list1.sortWith(_ < _)
    println(list3) //输出: List(10, 20, 30, 50, 60, 70)