问题:选出蜀国中五虎将
原始数据如下:
序号 姓名 武力值 国家
1 刘备 68 蜀国
2 马超 90 蜀国
3 黄忠 91 蜀国
4 魏延 76 蜀国
5 姜维 92 蜀国
6 关羽 96 蜀国
7 严颜 78 蜀国
8 孟达 64 蜀国
9 张飞 88 蜀国
10马谡 76 蜀国
11 赵云 95 蜀国
12 法正 88 蜀国
预期结果如下:
6 关羽 96 蜀国
11 赵云 95 蜀国
5 姜维 92 蜀国
3 黄忠 91 蜀国
2 马超 90 蜀国
准备工作
新建一个数据文件
将其传到hdfs上
hdfs dfs -put ~/wujiang.txt input
我的文件是在/home/wang 下
在hadoop web上查看
分析
通过对武力值排序,得到按武力值排序的数据,输出前五行即可。
讲解
自定义比较函数MyWritable,实现按武力值排序,并让其他数据一直跟随着武力值,以便后面输出完整的数据
MyWritable.java
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
public class MyWritable implements WritableComparable<MyWritable> {
private Integer num;
public String id;
public String name;
public String nation;
public MyWritable(Integer num, String a, String b, String c) {
this.num = num;
this.id=a;
this.name=b;
this.nation=c;
}
public MyWritable() {
}
@Override
public void write(DataOutput out) throws IOException {
out.writeUTF(id);
out.writeUTF(name);
out.writeInt(num);
out.writeUTF(nation);
}
@Override
public void readFields(DataInput in) throws IOException {
this.id=in.readUTF();
this.name=in.readUTF();
this.num = in.readInt();
this.nation=in.readUTF();
}
@Override
public int compareTo(MyWritable o) {
int minus = this.num - o.num;
return minus * (-1);
}
@Override
public int hashCode() {
return this.num.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof MyWritable) {
return false;
}
MyWritable ok2 = (MyWritable) obj;
return (this.num == ok2.num);
}
@Override
public String toString() {
return id+" "+name+" "+num +" "+nation;
}
}
Mapper中将读取进来的数据按空格切片,并调用MyWritable的构造方法传递数据过去完成排序
TopMapper.java
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class TopMapper extends Mapper<LongWritable, Text, MyWritable, Text> {
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString().trim();
if (line.length() > 0) {// 1,9819,100,121
String[] arr = line.split(" ");//按空格对读取进来的数据切片
if (arr.length == 4) {
String id=arr[0];
String name=arr[1];
int payment = Integer.parseInt(arr[2]);
String nation=arr[3];
context.write(new MyWritable(payment,id,name,nation), new Text(""));
}
}
}
}
Reduce类实现选出前五,并调用MyWritable对象的tostring方法,输出我们需要的完整数据
TopReducer.java
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class TopReducer extends Reducer<MyWritable, Text, Text, MyWritable> {
private int idx = 0;
@Override
protected void reduce(MyWritable key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
idx++;
if (idx <= 5) {
context.write(new Text( ""),key);
}
}
}
Top.java
打包程序(ubuntu下不好截图,请谅解下)
点击file
点击Project Struture
点击Artifacts一>JAR一>Empty
借的网上的图,ubuntu下不好截图,请谅解下
输入Name(打包后的名字) 选择Output directory(打包成功后存放的路径,能找到就行)
点击中间的+号
选择第一个Module Outout 选你项目名即可
点击Buils
选择Build Aritifacts一Top一Bulid
打包好之后
到之前填写的输出路径查看
hadoop
进入hadoop安装目录
cd /usr/local/hadoop
启动hadoop
./sbin/start-dfs.sh
将之前的打包后的Top.jar拷贝到hadoop目录下
使用hadoop jar命令 运行Top.jar
hadoop jar Top.jar Top input/wujiang.txt output
Top.jar为包名,Top为主类名,input/test.txt为数据所在路径,output为输出路径
成功
查看结果
hdfs dfs -cat outout/*
注意:每次运行完之后需要将output文件夹删掉之后,才能进行下一次调试
hdfs dfs -rm -r output
有问题请留言,博主会尽力解决
来源:CSDN
作者:Late whale
链接:https://blog.csdn.net/Late_whale/article/details/103480944