自定义排序WritableComparable
排序是MapReduce框架中重要的操作之一,其中MapTask和ReduceTask都会对数据按照key进行排序,这是Hadoop默认进行的操作。任何应用程序中的数据均会被排序,而不管逻辑上是否需要。一个MapReduce程序涉及了多种排序,而且相同类型的排序可能还进行了多次。其中,我们也可以自行定义排序来让MapReduce的处理结果达到我们想要的结果。而我们想要自定义排序,那就必须继承WritableComparable这个接口,看一下这个接口:
public interface WritableComparable<T> extends Writable, Comparable<T> { }
它继承了Writable接口和Comparable接口,由于WritableComparable中没有定义要实现的方法,所以继承这个接口,要实现的方法都是Writable接口和Comparable接口中的方法,它们主要有以下几个:
对于Writable接口,要实现write和readFields方法,write是要对out对象进行序列化操作,readFields是对in对象进行反序列化操作。
public interface Writable { /** * Serialize the fields of this object to <code>out</code>. * * @param out <code>DataOuput</code> to serialize this object into. * @throws IOException */ void write(DataOutput out) throws IOException; /** * Deserialize the fields of this object from <code>in</code>. * * <p>For efficiency, implementations should attempt to re-use storage in the * existing object where possible.</p> * * @param in <code>DataInput</code> to deseriablize this object from. * @throws IOException */ void readFields(DataInput in) throws IOException; }
Comparable接口,它的作用是将调用该方法的对象和传入参数对象进行比较:
public int compareTo(T o);
返回值有三种:负整数,此时调用该方法的对象小于指定对象;0,二者相等;正整数,调用该方法的对象大于指定对象。
因为比较是针对key进行排序的,所以如果我们要想自定义对map处理后的数据排序,那么就应该map输出的数据中的key的类型应是我们自定义的,并且实现了WritableComparable接口,那么实现这个接口应该怎么写实现类呢,让我们看一下这个示例:
public class MyWritableComparable implements WritableComparable<MyWritableComparable> { // Some data private int counter; private long timestamp; public void write(DataOutput out) throws IOException { out.writeInt(counter); out.writeLong(timestamp); } public void readFields(DataInput in) throws IOException { counter = in.readInt(); timestamp = in.readLong(); } public int compareTo(MyWritableComparable o) { int thisValue = this.value; int thatValue = o.value; return (thisValue < thatValue ? -1 : (thisValue==thatValue ? 0 : 1)); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + counter; result = prime * result + (int) (timestamp ^ (timestamp >>> 32)); return result } }
注意,实现序列化和反序列化方法时,写入和读取属性的顺序一定要相同!!!实现完成之后,这个实现类就可以作为Map阶段输入或者输出数据的key类型,进行输出。要想自定义排序,最核心的逻辑代码就在compareTo方法中。
原文地址:https://www.cnblogs.com/yxym2016/p/12993895.html
- 探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)
- 洛谷P3383 【模板】线性筛素数(Miller_Rabin)
- BZOJ3667: Rabin-Miller算法
- Numpy 修炼之道 (2)—— N维数组 ndarray
- python爬虫入门(五)Selenium模拟用户操作
- python爬虫入门(六) Scrapy框架之原理介绍
- lambda表达式杂谈
- python爬虫入门(七)Scrapy框架之Spider类
- python爬虫入门(八)Scrapy框架之CrawlSpider类
- python爬虫入门(九)Scrapy框架之数据库保存
- Numpy 修炼之道(1) —— 什么是 Numpy
- TensorFlow修炼之道(3)——计算图和会话(Graph&Session)
- 1.python简介
- 《Python自然语言处理》答案第三章
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Spartacus CmsPage的加载逻辑
- JUnit 5 测试 Spring 引擎的时候提示 junit-vintage 错误
- SAP Spartacus activeBaseSite的设置逻辑
- SAP Spartacus取语言设置的入口程序
- 几行 Python 代码实现文字识别,你敢信?
- SAP Spartacus的navigation初始化
- 大数据ETL实践探索 ---- 笔试面试考点
- jQuery 效果
- jQuery 样式操作
- Nginx 限制资源的访问
- 如何设计一个秒杀系统
- Linux下登录凭证窃取技巧
- kali修改root密码
- PPT画成这样,述职答辩还能过吗?
- 详解 Cookie,Session,Token