前言
之前写过一篇MapReduce对CSV文件去空去重,虽然能实现功能但是还有很多地方需要改进,刚好有新爬好的智联招聘的职位信息,所以再来一遍,
这里只对职位名称或职位描述字段为空的数据删除,因为爬出来的数据比较规范没有空值和重复值,可以自己人为制造一些不符合规范的数据
话不多说上代码,改进了的地方在代码后列出,详细注释上一篇有就不写了
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
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;
import java.io.IOException;
public class Zhilian {
public static Text nullData = new Text("");
public static Text text = new Text("");
public static class Map extends Mapper<Object, Text, Text, Text>{
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
if(isRightData(line)){
String data = line.replace(",", "|");
text.set(data);
context.write(text, nullData);
}
}
//只判断职位名称和职位描述是否为空
boolean isRightData(String line){
Boolean flag = true;
String[] items = line.split(",");
if(items[7].trim().isEmpty() || items[8].trim().isEmpty()){
flag = false;
}
return flag;
}
}
public static class Reduce extends Reducer<Text, Text, Text, Text> {
public void reduce(Text key, Iterable<Text> value, Context context) throws IOException, InterruptedException {
context.write(key, nullData);
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Configuration conf = new Configuration();
Job job = Job.getInstance();
job.setMapperClass(Map.class);
job.setCombinerClass(Reduce.class);
job.setReducerClass(Reduce.class);
job.setJarByClass(Zhilian.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
Path in = new Path("hdfs://192.168.1.101:9000/in/zhilian.csv");
Path out = new Path("hdfs://192.168.1.101:9000/out/");
FileSystem fileSystem = FileSystem.get(conf);
fileSystem.delete(out, true);
FileInputFormat.addInputPath(job, in);
FileOutputFormat.setOutputPath(job, out);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
改进
1、在之前的代码中,key或value不需要输出值时用的是new Text(""),改进为提前new一个类型为Text值为空的静态变量Text nullData = new Text(""),要输出值为空的Text型数据时直接输出nullData,减少了new来开辟空间的次数就减少了内存的占用
2、因为在输出时要把String类型值转化为Text类型,用的方式也是new Text(data),也是不断new,优化方法创建一个静态Text类型变量Text text = new Text(""),输出data时text.set(data)直接把text输出
3、运行结束后会在我们设定的hdfs目录下生成路径和文件,但如果此路径或文件存在来,就会报出路径或文件已存在的异常,所以每一次运行前都要先递归删除这个路径,很麻烦,所以这次会先判断输出路径,如果这个路径或文件已存在就删了,更人性化了