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