学生成绩参考:https://pan.baidu.com/s/1h8IhPwLaAv39N7yOH-Gv8g
二次排序:
依次按照多个条件进行排序
MapReduce 的所有排序都是针对 key 进行的,通常 key 只包含一列数据,
如果想让 key 包含多列数据,通常会自定义 key 实现
学生信息按照语文成绩降序排列,如果语文成绩相同,按照数学成绩降序排列
自定义 key 类型包含语文成绩和数学成绩两列的值
1. 创建类实现 WritableComparable 接口
2. 泛型设置为自定义 key 的类型
3. 声明需要包含的列为属性,并生成 getter && setter 方法
4. 实现接口中的 3 个方法
write:
按照属性的声明顺序依次输出
readFields:
按照属性的声明顺序依次读取
compareTo:
设置排序规则:
返回 0 按照 ab 排序
返回 1 按照 ba 排序
返回 -1 按照 ab 排序
学生信息按照总成绩降序排列,
如果总成绩相同,按照语文成绩降序排列,
如果语文成绩相同,按照数学成绩降序排列
package com.it666.student;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* @author 吴振峰
* 编程夜当午,手握小滑鼠。
* 谁知编程辛,行行皆'心'苦。
*/
public class Core4 {
private static class ScoreA4Key implements WritableComparable<ScoreA4Key>{
private Integer yuwen; //语文成绩
private Integer shuxue; //数学成绩
//set get
public Integer getYuwen() {
return yuwen;
}
public void setYuwen(Integer yuwen) {
this.yuwen = yuwen;
}
public Integer getShuxue() {
return shuxue;
}
public void setShuxue(Integer shuxue) {
this.shuxue = shuxue;
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(yuwen);
out.writeInt(shuxue);
}
@Override
public void readFields(DataInput in) throws IOException {
yuwen = in.readInt();
shuxue = in.readInt();
}
@Override
public int compareTo(ScoreA4Key o) {
//拿this 和 o 进行比较 作为排序规则
//this == a o == b
if (this.getYuwen() == o.getYuwen()) {
//语文成绩相同,按照数学成绩排序
if (this.getShuxue() == o.getShuxue()) {
return 0;
}else if(this.getShuxue() > o.getShuxue()) {
return -1;
}else {
return 1;
}
}else if(this.getYuwen() > o.getYuwen()) {
return -1;
}else {
return 1;
}
}
}
private static class ScoreA4Mapper extends Mapper<LongWritable, Text, ScoreA4Key, Text>{
private ScoreA4Key outputkey = new ScoreA4Key();
private Text outputvalue = new Text();
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, ScoreA4Key, Text>.Context context)
throws IOException, InterruptedException {
String line = value.toString();
String[] words = line.split("\\s+");
String name = words[0];
Integer yuwen = Integer.parseInt(words[1]);
Integer shuxue = Integer.parseInt(words[2]);
//以语文数学成绩为 key ,名字 value 进行输出
outputkey.setYuwen(yuwen);
outputkey.setShuxue(shuxue);
outputvalue.set(name);
context.write(outputkey, outputvalue);
}
}
private static class ScoreA4Reducer extends Reducer<ScoreA4Key, Text, Text, NullWritable>{
private Text outputkey = new Text();
@Override
protected void reduce(ScoreA4Key key, Iterable<Text> values,
Reducer<ScoreA4Key, Text, Text, NullWritable>.Context context) throws IOException, InterruptedException {
for (Text name : values) {
outputkey.set(name.toString() + "\t\t" + key.getYuwen() +"\t" + key.getShuxue());
context.write(outputkey, NullWritable.get());
}
}
}
public static void main(String[] args) {
Configuration conf = new Configuration();
try {
Job job = Job.getInstance(conf);
job.setJarByClass(Core4.class);
job.setMapperClass(ScoreA4Mapper.class);
job.setReducerClass(ScoreA4Reducer.class);
job.setMapOutputKeyClass(ScoreA4Key.class);
job.setMapOutputValueClass(Text.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
Path inputPath = new Path("E:/java/MavenHadoopData/04-Students Grade/scoreB.txt");
FileInputFormat.addInputPath(job, inputPath);
Path outputPath = new Path("E:/java/MavenHadoopData/04-Students Grade/scoreA4");
FileSystem.get(conf).delete(outputPath, true);
FileOutputFormat.setOutputPath(job, outputPath);
job.waitForCompletion(true);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}