Mapreduce自定义分组器
前提:有的时候我们想将符合条件的key值放在同一个组内;但是key的值是不同的将不会放进同一个组中。
举例:想将一个学生的进校以后不同时间段的数学成绩按进校考试的时间进行一个成绩排序。如下效果
//排序前的效果
stu1 time1 core1
stu1 time2 core
stu1 time3 core3
stu2 time1 core1
stu2 time2 core3
stu2 time3 core2
//排序后的效果
stu1 core3,core2,core1
stu2 core2,core3,core1
方法:
- 说明:提前就已经重新定义了数据类型,类型定义如下:
public class OneKey implements WritableComparable {
private String first;
private String secend;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
OneKey myKey = (OneKey) o;
return Objects.equals(first, myKey.first) &&
Objects.equals(secend, myKey.secend);
}
@Override
public int hashCode() {
return Objects.hash(first, secend);
}
public OneKey() {
super();
}
public OneKey(String first, String secend) {
this.first = first;
this.secend = secend;
}
public void setFirst(String first) {
this.first = first;
}
public void setSecend(String secend) {
this.secend = secend;
}
public String getFirst() {
return first;
}
public String getSecend() {
return secend;
}
@Override
public int compareTo(Object o) {
OneKey o1 = (OneKey)o;
int ans = this.first.compareTo(o1.getFirst());
if(ans != 0){
return ans;
}
return o1.getSecend().compareTo(this.secend);
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(this.first);
out.writeUTF(this.secend);
}
@Override
public void readFields(DataInput in) throws IOException {
this.first = in.readUTF();
this.secend = in.readUTF();
}
}
public class OneComparator extends WritableComparator {
public OneComparator() {
super(OneKey.class,true);
}
@Override
public int compare(WritableComparable a, WritableComparable b) {
OneKey a1 = (OneKey)a;
OneKey b1 = (OneKey) b;
return a1.getFirst().compareTo(b1.getFirst());
}
}
import java.io.IOException;
public class OneMapper extends Mapper<LongWritable, Text, OneKey,Text> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String lines = value.toString();
String[] strings = lines.split(",");
OneKey oneKey = new OneKey();
oneKey.setFirst(strings[0]);
oneKey.setSecend(strings[1]);
context.write(oneKey, new Text(strings[2]));
}
}
public class OneReducer extends Reducer<OneKey, Text, Text, Text> {
@Override
protected void reduce(OneKey key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
StringBuilder sb=new StringBuilder();
for (Text text: values) {
sb.append(text.toString()).append(",");
}
context.write(new Text(key.getFirst()), new Text(sb.substring(0, sb.length()-1)));
}
}
public class OneDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
String inputPath = "E:/Test-workspace/test/input/2-1.txt";
String outputPath = "E:/Test-workspace/test/output/2-1";
Configuration configuration = new Configuration();
Job instance = Job.getInstance(configuration);
instance.setJarByClass(OneDriver.class);
instance.setGroupingComparatorClass(OneComparator.class);
instance.setMapperClass(OneMapper.class);
instance.setReducerClass(OneReducer.class);
instance.setMapOutputKeyClass(OneKey.class);
instance.setMapOutputValueClass(Text.class);
instance.setOutputKeyClass(Text.class);
instance.setOutputValueClass(Text.class);
FileInputFormat.setInputPaths(instance, inputPath);
FileOutputFormat.setOutputPath(instance, new Path(outputPath));
boolean waitForCompletion = instance.waitForCompletion(true);
System.exit(waitForCompletion?0:1);
}
}