Spark rdd之sortBy

源码

 def sortBy[K](
      f: (T) => K,
      ascending: Boolean = true,
      numPartitions: Int = this.partitions.length)
      (implicit ord: Ordering[K], ctag: ClassTag[K]): RDD[T] = withScope {
    this.keyBy[K](f)
        .sortByKey(ascending, numPartitions)
        .values
  }

第一个参数是一个函数,该函数的也有一个带T泛型的参数,返回类型和RDD中元素的类型是一致的;

第二个参数是ascending,从字面的意思大家应该可以猜到,是的,这参数决定排序后RDD中的元素是升序还是降序,默认是true,也就是升序;

第三个参数是numPartitions,该参数决定排序后的RDD的分区个数,默认排序后的分区个数和排序之前的个数相等,即为this.partitions.size。

从sortBy函数的实现可以看出,第一个参数是必须传入的,而后面的两个参数可以不传入。
而且sortBy函数函数的实现依赖于keyBy和sortByKey函数,后面会进行说明

示例

    val list: RDD[String] = sc.parallelize(List("taoge,38,99.99", "hangge,32,99.99", "xingge,18,9999.99"))

    val tfboys: RDD[Boy] = list.map(f => {
      val fields: Array[String] = f.split(",")
      val name: String = fields(0)
      val age: Int = fields(1).toInt
      val fv: Double = fields(2).toDouble
      Boy(name, age, fv)
    })
    //先按照fv 降序排序, 相同后按照年龄升序排序
    val sorted1: RDD[Boy] = tfboys.sortBy(f => (-f.fv, f.age)) //借助tuple实现排序规则,注意分区数
	
	sorted1.foreach(f => {
        println(f.toString)
      })
    sc.stop()
  }
}
case class Boy(name:String,age:Int,fv:Double)

在这里插入图片描述

sortBy底层实现(keyBy+sortByKey)

//sortBy内部实现方式
    val keybyed: RDD[((Double, Int), Boy)] = tfboys.keyBy(t => (-t.fv, t.age))
    val sorted2: RDD[Boy] = keybyed.sortByKey().values
    
    sorted2.foreach(f => {
      println(f.toString)
    })

sortBy + 隐式参数实现自定义排序[方式1]


    //先按照fv 降序排序, 相同后按照年龄升序排序
   implicit val order: Ordering[Boy1] = new Ordering[Boy1] {
      override def compare(x: Boy1, y: Boy1): Int = {
        if (x.fv == y.fv) {
          x.age - y.age
        } else {
          java.lang.Double.compare(y.fv, x.fv)
        }
      }
    }
    tfboys.sortBy(f=>f).foreach(f=>{
      println(f.toString)})

sortBy + 隐式参数实现自定义排序[方式2]

    //先按照fv 降序排序, 相同后按照年龄升序排序
    //借助元祖,元祖规则先比较第一个在比较第二个
   implicit val order: Ordering[Boy1] = Ordering[(Double,Int)].on[Boy1](b=>(-b.fv,b.age))
    tfboys.sortBy(f=>f).foreach(f=>{
      println(f.toString)})

自定义排序+sortBy

  //先按照fv 降序排序, 相同后按照年龄升序排序
    tfboys.sortBy(f=>f).foreach(f=>{
      println(f.toString)})
  }
}
//todo 实现Oredered接口,实现compare方法,而不是java的Comparable接口 Comparable的compareTo方法底层调用的还是compare方法
//  先按照fv 降序排序, 相同后按照年龄升序排序
case class Boy(name:String,age:Int,fv:Double) extends Ordered[Boy] {
  /**
   *  x < 0 when this < that
      x == 0 when this == that
      x > 0 when this > that
   */
  override def compare(that: Boy): Int = {
    if (this.fv==that.fv){
      this.age - that.age
    }else{
      java.lang.Double.compare(that.fv , this.fv)
    }
  }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值