总概述
(1)sorted
对一个集合进行自然排序,通过传递隐式的Ordering
(2)sortBy
对一个属性或多个属性进行排序,通过它的类型。
(3)sortWith
基于函数的排序,通过一个comparator函数,实现自定义排序的逻辑。
sorted
概念
排序很重要,将来在大数据里面做计算,无非就是各种的指标,按照指定业务进行top3或者top10排序啥的.只要求前几的,一定是排序操作.
scala:
不管是可变集合还是不可变集合, 都是返回一个新的排好的序集合
原集合不动
sorted
默认都是自然排序(升序)
- 让排序的类型有自己排序的功能
Ordered 就是java中的 Comparable - 找一个第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)