从零开始大数据【1.2】-- 自定义bean对象(数据类型)用于mapreduce task中
文章目录
上期回顾:
上一节中,介绍了最简单的mapreduce框架,编写了map,reduce以及driver三个程序,可以发现无论是map还是reduce过程参数的传递都采用了kv对的形式,其中k和v都有相应的数据类型,并在driver中做了约束,在mapreduce中基本的数据类型如下
- BooleanWritable
- ByteWritable
- DoubleWritable
- FloatWritable
- IntWritable
- LongWritable
- Text
- NullWritable
但是这些类型都很简单,而在实际应用中许多数据都带着其内在的结构,就像是c++中的类(比如班级学生信息有学号性别成绩等等),这是就需要自定义数据类型,即自定义bean对象。
自定义bean对象
由于mapreduce是在集群上运行的,即文件的传输是电脑与电脑之间的,不是存在内存中可以被简单读取的,因此需要设定该对象的序列化方法。
所谓序列化方法即让数据从内存中转到文件中的方法。
同样,该对象也需要反序列化的方法,即从文件中读到内存中。
注意点
在定义bean对象时有七点需要特别注意:
- 必须实现 Writable 接口
- 反序列化时,需要反射调用空参构造函数,所以必须有空参构造
public FlowBean() { super(); }
- 重写序列化方法
- 重写反序列化方法
- 注意反序列化的顺序和序列化的顺序完全一致
- 要想把结果显示在文件中,需要重写 toString(),可用”\t”分开,方便后续用。
- 如果需要将自定义的bean 放在 key 中传输,则还需要实现 comparable 接口,因为 mapreduce 框中的 shuffle 过程一定会对 key 进行排序。
实际案例
数据集使用了kaggle上的数据集,数据集如图所示
总共有13个列。为了体现bean,首先我们计算每个类别中的分数的总和(应该是平均值,但是试了一下没成功,先用总和之后熟悉了再改)以及评论数的平均值。
一开始使用了所有数据,结果一直失败,研究了快一个小时,终于学会了debug的方法然后发现是因为数据很多事不规范的,所以用parsedouble时会出错!!所以选取了一部分数据。
编写bean对象
package appmapreduce;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
public class nbean implements Writable {
private long reviews;
private double rating;
//空参构造(在source中 generate construct using fields)
public nbean() {
super();
}
public nbean(long reviews, double rating) {
super();
this.reviews = reviews;
this.rating = rating;
}
@Override
public String toString() {
return reviews +"\t"+rating;
}
//反序列化方法
@Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
this