在RDD中默认的算子sortBy,sortByKey只能真的值类型数据升序或者降序

现需要对自定义对象进行自定义排序。

一组Person对象

  /**
* Person 样例类
* @param name
* @param age
*/
case class Person1(name: String, age: Int) {
override def toString = {
"name: " + name + ",age: " + age
}
val list = List(Person1("tom", 12), Person1("tom1", 13), Person1("tom2", 13))

sortBy:单Value类型RDD排序

方法一:类继承Ordered

  //类继承Ordered
case class Person(name: String, age: Int) extends Ordered[Person] with Serializable {
//重写toString
override def toString = {
"name: " + name + ",age: " + age
} //自定义排序
override def compare(that: Person): Int = {
//先按照age降序排序
var result = -this.age.compareTo(that.age)
//如果age相同,按照name升序排序
if (result == 0) {
result = this.name.compareTo(that.name)
}
result
}
}

使用

    val list = List(Person("tom", 12), Person("tom1", 13), Person("tom2", 13))
val conf = new SparkConf().setAppName("RDDTest").setMaster("local[*]")
val sc = new SparkContext(conf)
sc.makeRDD(list).sortBy(x=>x).saveAsTextFile("output2")

方法二:实现Ordering

   //类不需要改动
case class Person1(name: String, age: Int) {
override def toString = {
"name: " + name + ",age: " + age
}

使用

    val list = List(Person1("tom", 12), Person1("tom1", 13), Person1("tom2", 13))
val rdd = sc.makeRDD(list)
//自定义排序: age降序,name升序,先按照谁排序,就放在前面 reverse:反转,降序
rdd.sortBy(person => (person.age, person.name), numPartitions = 1)(Ordering.Tuple2(Ordering.Int.reverse, Ordering.String)
, ClassTag(classOf[Tuple2[String, Int]])).saveAsTextFile("output5")

sortByKey:Key-Value类型RDD排序

只能针对key对k-v数据进行排序

方法一:类继承Ordered

同sortBy方法一,样例类继承ORdered

将单值转为K-V类型,key为Person对象。

方法二:实现Ordering

创建一个Person1类型的隐式Ordering[Person1]的比较器

import org.apache.spark.{SparkConf, SparkContext}

/**
* @description: TODO
* @author: HaoWu
* @create: 2020年08月04日
*/
object SortByKeyOrderingTest {
def main(args: Array[String]): Unit = {
//创建一个Person1类型的隐式Ordering[Person1]的比较器
implicit val ord = new Ordering[Person1] {
//自定义排序:age降序,name升序
override def compare(x: Person1, y: Person1): Int = {
//age降序
var result = -x.age.compareTo(y.age)
//name升序
if (result == 0){
result = x.name.compareTo(y.name)
}
result
}
}
val list = List(Person1("tom", 12), Person1("tom1", 13), Person1("tom2", 13))
val conf = new SparkConf().setAppName("RDDTest").setMaster("local[*]")
val sc = new SparkContext(conf)
val rdd = sc.makeRDD(list)
//转为K-V形式,按照key排序
rdd.map((_,1)).sortByKey().coalesce(1).saveAsTextFile("output")
}
} /**
* Person 样例类
* @param name
* @param age
*/
case class Person1(name: String, age: Int) {
override def toString = {
"name: " + name + ",age: " + age
}
}
结果:
(name: tom1,age: 13,1)
(name: tom2,age: 13,1)
(name: tom,age: 12,1)

最新文章

  1. js 阻止事件冒泡
  2. Android--SQLite的使用
  3. Hibernate的ORM原理和实现
  4. [Compose] 21. Apply Natural Transformations in everyday work
  5. 2015年第5本(英文第4本):Death on the Nile尼罗河上的惨案
  6. UML教程首页(转载)
  7. poj 3170
  8. Quartz定时调度CronTrigger时间配置格式说明与实例
  9. SQL语句中的DQL、DML、DCL、DDL、CCL、TPL
  10. awk 处理
  11. [AtCoder agc021D]Reversed LCS
  12. Spring Boot – 自定义PropertyEditor
  13. Jupyter Notebook的安装
  14. Python学习二十八周(vue.js)
  15. MyBatis基础入门《十九》动态SQL(set,trim)
  16. Linux安装MySQL8.0.12之二进制安装
  17. 人工智能-机器学习之numpy方法
  18. Pycharm远程连接服务器(windows下远程修改服务器代码)
  19. Android 开发工具类 23_getImage
  20. 使用Java创建XML数据

热门文章

  1. WPF_02_XAML
  2. linux下测试读写
  3. WPF进阶技巧和实战03-控件(4-基于范围的控件及日期控件)
  4. jmeter no-JUI执行常用命令(四)
  5. robot_framewok自动化测试--(9)连接并操作 MySql 数据库
  6. JDK源码阅读(5):HashTable类阅读笔记
  7. 学习JS的第二天
  8. 如何保证redis中存放的都是热点数据
  9. [第二章]c++学习笔记3(构造函数)
  10. 深刻理解Spring声明式事务