1.sorted方法真正排序的逻辑是调用的java.util.Arrays.sort。
源码:
def sorted[B >: A](implicit ord: Ordering[B]): Repr = {
val len = this.length
val b = newBuilder
if (len == 1) b ++= this
else if (len > 1) {
b.sizeHint(len)
val arr = new Array[AnyRef](len) // Previously used ArraySeq for more compact but slower code
var i = 0
for (x <- this) {
arr(i) = x.asInstanceOf[AnyRef]
i += 1
}
java.util.Arrays.sort(arr, ord.asInstanceOf[Ordering[Object]])
i = 0
while (i < arr.length) {
b += arr(i).asInstanceOf[A]
i += 1
}
}
b.result()
}
2.sortBy最后也是调用的sorted方法。不一样的地方在于,sortBy还需要传递一个参数,这个参数是一个函数。
源码:
def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr = sorted(ord on f)
sortBy可以传递一个函数,这个函数中可以定义 排序规则,然后列表中的元素根据 传递的函数规则进行 排序。
eg:
var lb = new ListBuffer[Int]
lb.append(1,2,9,4,5,2)
var lb2 = lb.sorted
lb2.foreach(x => println("lb2 : "+x))
println("---------------")
var sortTest = (i:Int) => {
i match {
case 1 => 2
case 2 => 1
case 4 => 0
case _ => 3
}
}
var lb3 = lb.sortBy(sortTest)
lb3.foreach(x => println("lb3: "+x))
输出:
可以看到 sorted 是直接排序, sortedBy 是引用了 我们定义的sortTest排序方法
这个排序的规则是,传入这个函数,必须只有一个Int类型的参数,然后进行类型匹配,遇到4了按照0进行排序,遇到2了按照1进行
排序,遇到1了按照2进行排序,其他的都按照3排序,也就是最大的。
2.2定义复杂排序规则
eg:
//create a Class Person
class Person(age:Int, salary:Double, name:String){
var Age = age
var Salary = salary
var Name = name
}
val lisa = new Person(38, 2.3, "lisa")
val nana = new Person(1, 3.4, "nana")
val zhaoSi = new Person(1, 5.9, "赵四")
val grandpa = new Person(80, 20, "grandpa")
//create a list
var listPerson = new ListBuffer[Person]
listPerson.append(lisa, nana, zhaoSi, grandpa)
//create a sort rule
var sortRule = (p:Person) => {
(p.Age, p.Salary, p.Name)
}
//list sort use the list Rule
var listPersonSorted = listPerson.sortBy(sortRule)(Ordering.Tuple3(Ordering.Int.reverse, Ordering.Double.reverse,
Ordering.String.reverse))
listPersonSorted.foreach(x => println(x.Name, x.Age, x.Salary))
输出:
按照年龄、薪水、姓名排序
如果只按照 年龄和薪水排序:
改为
//create a Class Person
class Person(age:Int, salary:Double, name:String){
var Age = age
var Salary = salary
var Name = name
}
val lisa = new Person(38, 2.3, "lisa")
val nana = new Person(1, 3.4, "nana")
val zhaoSi = new Person(1, 5.9, "赵四")
val grandpa = new Person(80, 20, "grandpa")
//create a list
var listPerson = new ListBuffer[Person]
listPerson.append(lisa, nana, zhaoSi, grandpa)
//create a sort rule
var sortRule = (p:Person) => {
(p.Age, p.Salary)
}
//list sort use the list Rule
var listPersonSorted = listPerson.sortBy(sortRule)(Ordering.Tuple2(Ordering.Int.reverse,
Ordering.Double.reverse
))
listPersonSorted.foreach(x => println(x.Name, x.Age, x.Salary))
修改红色部分即可
3.sortWith最后也是调用的sorted方法。不一样的地方在于,sortWith需要传入一个比较函数用来比较
def sortWith(lt: (A, A) => Boolean): Repr = sorted(Ordering fromLessThan lt)
eg:
//忽略大小写排序
def compareIngoreUpperCase(e1: String, e2: String) : Boolean = {
e1.toLowerCase < e2.toLowerCase
}
def test2() = {
val list = List( "a", "g", "F", "B", "c")
val sortWithList1 = list.sortWith(_ < _) // List(B, F, a, c, g)
val sortwithList2 = list.sortWith((left, right) => left < right) //List(B, F, a, c, g)
val sortwithList3 = list.sortWith(compareIngoreUpperCase) // List(a, B, c, F, g)
println(sortWithList1)
println(sortwithList2)
println(sortwithList3)
}