将以下进行排序:
a 1
a 9
b 3
a 7
b 8
b 10
a 5
a 9
我要实现的效果如下:
a 9
a 9
a 7
a 5
a 1
b 10
b 8
b 3
字母由小到大排列,数字由大到小排列。
分析如下:因为两列都要进行排序比较,所以这个k1,v1,k2,v2,k3,v3应该如何设置?
k1还是行偏移量,v1对应的是一行文本,我们可以将整体作为一个对象。定义成一个pairSort类。该类要实现的功能就是排序。
pairSort类
package com.legendlee.sort;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class pairSort implements WritableComparable<pairSort> {
//类有两列,所以需要定义两个字段
//字母
private String first;
//数字
private Integer second;
@Override
public String toString() {
return first+"\t"+second;
}
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public Integer getSecond() {
return second;
}
public void setSecond(Integer second) {
this.second = second;
}
/**
* 这个方法是实现比较器,返回0,相等
* 正数 第一个比第二个大
* 负数 第一个比第二个小
*
a 1
a 9
b 3
a 7
b 8
b 10
a 5
a 9
*
* @param o
* @return
*/
@Override
public int compareTo(pairSort o) {
//比较第一列的数据,即a和b进行比较
int i = this.first.compareTo(o.first);
//判断a,b的大小
//若i不等于0,表明a和b不相等
if(i!=0){
return i;
}else {
//如果第一列相等,则比较第二列
int i1 = this.second.compareTo(o.second);
return i1;
}
}
/**
* 序列化的方法
* @param out
* @throws IOException
*/
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(first);
out.writeInt(second);
}
/**
* 反序列化的方法
* @param in
* @throws IOException
*/
@Override
public void readFields(DataInput in) throws IOException {
this.first=in.readUTF();
this.second=in.readInt();
}
}
sortMapper类
思考:接收的k1,v1是什么类型,输出的k2,v2是什么类型?
k1:偏移量 IntWritable
v1:文本 Text
k2: pairSort对象
v2: 文本 Text
package com.legendlee.sort;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class sortMapper extends Mapper<IntWritable,Text,pairSort,Text> {
/**
* mapper阶段:将k2,v2提交给reducer处理
* @param key
* @param value
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(IntWritable key, Text value, Context context) throws IOException, InterruptedException {
pairSort pairSort = new pairSort();
//将文本内容进行切割
String[] split = value.toString().split("\t");
//将切割后的内容添加到pairSort对象中
pairSort.setFirst(split[0]);
pairSort.setSecond(Integer.parseInt(split[1]));
//将k2,v2提交给reduce处理
context.write(pairSort,value);
}
}
sortReducer类
package com.legendlee.sort;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class sortReducer extends Reducer<pairSort,Text,pairSort,NullWritable> {
/**
*reducer:直接输出即可
* @param key
* @param values
* @param context
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(pairSort key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
context.write(key,NullWritable.get());
}
}
sortMain类