作用
将对象持久化或者在网络中传输, 需要将其转换成字节流, 这就是序列化; 反之, 从磁盘或者网络中将字节流读取转换成为对象, 这就是反序列化;
hadoop开发了自己的序列化和反序列化, 为什么没有使用Java已经实现的解决方式呢?
因为, Java将对象进行序列化方式相对重量级, 一个对象序列化之后会附带很多额外信息,例如,校验信息, 继承关系等, 不便于网络传输. 于是hadoop重新实现了一套解决方案, 精简高效, 需要哪个属性就传递哪个属性, 大大减少了网络开销.
实现方案
Writable接口是Hadoop的序列化接口, 一个类需要实现序列化, 只需要实现这个接口
WritableComparable是Writable的子接口, 在实现序列化的同时, 也实现了对象的比较, 可以用于对象数据的排序
案例实战
需求
对学生成绩进行由大到小排序, 如果成绩相同的学生, 按照名字进行字母正序排序
数据样例
name制表符score
Mark 100
Tom 100
Lucy 88
Lily 90
HaiMeimei 100
LiLei 98
MaYun 59
MaHuateng 60
思路
1.1, 自定义Student类, 实现WritableComparable接口;
1.2, 接口的比较方法compareTo()方法, 首先针对成绩做大道小排序, 相同则按照名字进行字母正序排序.
2, 创建Mapper类
3, 创建Job启动类
代码实现
JavaBean类
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class Student implements WritableComparable<Student> {
private String name;
private Integer score;
public Student() {
}
public Student(String name, Integer score) {
this.name = name;
this.score = score;
}
/**
* 排序逻辑位置
*
* @param stu
* @return
*/
@Override
public int compareTo(Student stu) {
//1, 比较逻辑: 首先比较两个Student对象的Score大小,这里计算的正序, 需求是逆序, 所辖else逻辑里面* -1
int compare = this.score.compareTo(stu.getScore());
//2, 比较逻辑, 如果上面的Score比较相同, 那么比较两个Student的name属性, 需求是正序
if (compare == 0) {
return this.name.compareTo(stu.getName());
} else {
return -1 * compare;
}
}
/**
* 序列化逻辑位置
*
* @param out
* @throws IOException
*/
@Override
public void write(DataOutput out