Scala中sorted、sortBy、sortWith区别

本文详细介绍了Scala中`sorted`、`sortBy`和`sortWith`三种排序方法的实现原理和使用示例。`sorted`直接进行排序,`sortBy`允许自定义排序规则,`sortWith`通过传入比较函数进行排序。示例展示了如何根据年龄、薪水和姓名复杂排序,以及如何忽略大小写排序字符串。
摘要由CSDN通过智能技术生成

 

 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)
    }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值