1.数据
要求:对每个orderid列出成交额最大的前n条记录。
2.思路
map任务:将每一行都映射为<orderid,orderBean>,orderid相同的为同一组,orderBean为对数据的封装类
reduce任务:对同一组的数据进行处理,即按成交额从大到小排序,输出前n条即可
1.orderBean类需要实现序列化接口Writable,重写readFields方法(反序列化)和write方法(序列化)
public class OrderBean implements Writable{
private String uid;
private String oid;
private String item;
private int num;
private float price;
public OrderBean() {
}
public OrderBean(String uid, String oid, String item, int num, float price) {
this.uid = uid;
this.oid = oid;
this.item = item;
this.num = num;
this.price = price;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
@Override
public String toString() {
return "OrderBean [uid=" + uid + ", oid=" + oid + ", item=" + item + ", num=" + num + ", price=" + price + "]";
}
//mr框架在将二进制数据反序列化成本类的对象时要调用的方法
//反序列化流程:先从本类反射出一个没有数据的对象,然后从二进制数据中反序列化出各个数据,然后set到这个反射出来的对象
public void readFields(DataInput in) throws IOException {
this.uid = in.readUTF();
this.oid = in.readUTF();
this.item = in.readUTF();
this.num = in.readInt();
this.price = in.readFloat();
}
//mr框架在将本类的对象进行序列化操作时要调用的方法
public void write(DataOutput out) throws IOException {
out.writeUTF(this.uid);
out.writeUTF(this.oid);
out.writeUTF(this.item);
out.writeInt(this.num);
out.writeFloat(this.price);
}
}
2.OrderTopnMapper类继承Mapper<LongWritable, Text, Text, OrderBean>
public class OrderTopnMapper extends Mapper<LongWritable, Text, Text, OrderBean>{
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, OrderBean>.Context context)
throws IOException, InterruptedException {
// u01,order001,apple,5,8.5
String[] split = value.toString().split(",");
OrderBean orderBean = new OrderBean(split[0], split[1], split[2], Integer.parseInt(split[3]), Float.parseFloat(split[4]));
context.write(new Text(orderBean.getOid()), orderBean);
}
}
3.OrderTopnReducer类继承Reducer<Text, OrderBean, OrderBean, NullWritable>
public class OrderTopnReducer extends Reducer<Text, OrderBean, OrderBean, NullWritable>{
@Override
protected void reduce(Text key, Iterable<OrderBean> values,
Reducer<Text, OrderBean, OrderBean, NullWritable>.Context context) throws IOException, InterruptedException {
ArrayList<OrderBean> beans = new ArrayList();
//每次迭代创建新对象
for (OrderBean orderBean : values) {
OrderBean beanNew = new OrderBean();
try {
BeanUtils.copyProperties(beanNew, orderBean);
} catch (Exception e) {
e.printStackTrace();
}
beans.add(beanNew);
}
//设置一个比较器,重写compare方法
Collections.sort(beans, new Comparator<OrderBean>() {
//返回-1:o1排在o2前面;返回1:o1排在o2后面;
public int compare(OrderBean o1, OrderBean o2) {
return o1.getNum()*o1.getPrice()-o2.getNum()*o2.getPrice()>0?1:-1;
}
});
for(int i=0;i<2;i++){
context.write(beans.get(i), NullWritable.get());
}
}
}
4.结果