序列化
将对象(文件)的状态信息转换成可存储的字节序列的过程。反过来就是反序列化。hadoop中的所有key/value都必须实现以下接口。
Writable 接口
public interface Writable{
//将对象状态信息写入二进制的DataOutput流(序列化)
void write(DataOutput out) throws IOException;
//从二进制的DataInput流中读取对象状态(反序列化)
void readFields(DataInput in) throws IOException;
}
对特定的Writable可以进行赋值和取值操作(以IntWritable为例)
IntWritable value = new IntWritable();
value.set(5567);//用set()方法赋值
/**
*
IntWritable value = new IntWritable(5567);//或者用构造方法赋值
*
**/
int result = value.get();//通过get()方法取值
Comparable接口
实现了Comparable的对象可以和自身相同类型的对象比较大小
public interface Comparable{
//将T对象和对象o进行比较,约定:返回负数为小于,零为大于,整数为大于
public int compareTo(T O);
}
WritableComparable
所有的key必须实现Comparable接口,value只用实现Writable接口。在MapReduce过程中需要对Key/Value对进行反复的排序。默认情况下依据Key进行排序的,要实现comparaTo()方法。所以通过Key既要实现Writable接口又要实现Comparable接口,把两个接口合为一个公共接口WritableComparable。
自定义一个WritableCpmparable类型的Example
public class TextPair implements WritableComparable {
private Text first;//Text 类型的实例对象
private Text second;
public TextPair() {
set(newText(),newText());
}
public TextPair(String first, String second) {
set(new Text(first),new Text(second));
}
public TextPair(Text first, Text second) {
set(first, second);
}
public void set(Text first, Text second) {
this.first = first;
this.second = second;
}
public Text getFirst() {
return first;
}
public Text getSecond() {
return second;
}
//序列化
@Override
public void write(DataOutput out)throwsIOException {
first.write(out);
second.write(out);
}
/**
在排序之前,需要先从磁盘中读取数据进行反序列化成对象,然后在内存中对反序列化的对象进行比较。
*/
//反序列化
@Override
public void readFields(DataInput in)throwsIOException {
first.readFields(in);
second.readFields(in);
}
//返回哈希值
@Override
public int hashCode() {
return first.hashCode() *163+ second.hashCode();
}
@Override
public boolean equals(Object o) {
//判定o是否与TextPair同等类型
if(o instanceof TextPair) {
TextPair tp = (TextPair) o;
return first.equals(tp.first) && second.equals(tp.second);
}
return false;
}
@Override
publicString toString() {
return first +"\t"+ second;
}
//排序
@Override
public int compareTo(TextPair tp) {
int cmp = first.compareTo(tp.first);
if(cmp !=0) {
return cmp;
}
return second.compareTo(tp.second);
}
}