测试数据,如wordcount.txt文本,内容如下:
I love Guiyang
I love Guizhou
Guiyang is the capical of Guizhou
1.定义WordCountMapper,继承于Hadoop的Mapper
package com.mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.VLongWritable;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**四个泛型解释:
* KEYIN :k1 的类型 long -->longWritable
* VALUEIN :v1 的类型 String -->Text //为了解决序列化的问题
* KEYOUT: K2 的类型 String
* VALUEOUT :V2的类型 long
*/
public class WordCountMapper extends Mapper <LongWritable,Text , Text, LongWritable>{
//重写map方法 ,map方法就是将 K1 和 V1 转为 K2 和 V2
/* 参数: key ; k1 行偏移量
* value :v1 每一行的文本数据
* context : 表示上下文对象
* 如何将K1 和 V1 转为 K2 和 V2
* K1 v1
* 0 I Love Guiyang
* 12 I Love Guizhou
* 24 Guiyang is the capital of Guizhou
*
* K2 V2
* I 1
* I 1
* Love 1
* Love 1
* Guiyang 1
* Guiyang 1
* Guizhou 1
* ...
* */
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
Text text = new Text();
LongWritable longWritable = new LongWritable();
//1.将一行的文本进行拆分
String[] split = value.toString().split(" ");
//2.遍历数组,组装 K2 和 V2
for (String word : split){
//3. 将 K2 和 V2 写入上下文中
text.set(word);
longWritable.set(1);
context.write(text, longWritable);
}
}
}
2.定义WordCountReducer,继承于Hadoop的Reducer
package com.mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**四个泛型解释:
* KEYIN :k2 的类型 String --> Text
* VALUEIN :v2 的类型 long -->LongWritable
* KEYOUT: K3 的类型 String --> Text
* VALUEOUT :V3的类型 long -->LongWritable
*/
public class WordCountReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
//将新的 K2 和 V2 转为 K3和 V3,将 K3 和 V3 写到上下文中
/*
参数:
key :新K2
value 集合 新 K2
context ;表示上下文对象
-------------------------------
如何将新的K2 和 V2 转为 K3 和 V3
新 K2 V2
I <1,1>
love <1,1>
Guiyang <1,1>
-----------------------------------------------
K3 V3
I 2
Love 2
Guiyang 2
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
long count = 0;
//1. 遍历集合 ,将集合中的数字相加,得到V3
for (LongWritable value : values) {
count += value.get();
}
// 2.将K3 和V3 写入上下文中
context.write(key,new LongWritable(count));
}
}
3.定义JobMain
package com.mapreduce;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class JobMain extends Configured implements Tool {
//该方法用于指定一个job任务
public int run(String[] strings) throws Exception {
//1.创建一个job任务对象
Job job = Job.getInstance(super.getConf(), "wordcount");
//2.配置job任务对象(8个步骤)
//第一步:指定文件的读取方式和读取路径
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job,new Path("file:///D:\\hadoop测试文件\\wordcount.txt"));
//第二步:指定map阶段的处理方式和数据类型
job.setMapperClass(WordCountMapper.class);
//设置map阶段 K2 的类型
job.setMapOutputKeyClass(Text.class);
//设置map阶段V2 的类型
job.setMapOutputValueClass(LongWritable.class);
//第三四五六 ,采用默认的方式 ,以后再说
//第七步:指定reduce阶段的处理方式和数据类型
job.setReducerClass(WordCountReducer.class);
//设置K3的类型
job.setOutputKeyClass(Text.class);
//设置V3的类型
job.setOutputValueClass(LongWritable.class);
//第八步:设置输出类型
job.setOutputFormatClass(TextOutputFormat.class);
//设置输出的路径
TextOutputFormat.setOutputPath(job,new Path("file:///D:\\hadoop测试文件\\ouput"));
//等待任务结束
boolean bl = job.waitForCompletion(true);
return bl ? 0:1 ;
}
public static void main(String[] args) throws Exception {
Configuration configuration = new Configuration();
//启动job任务
int run = ToolRunner.run(configuration, new JobMain(), args);
System.exit(run);
}
}
测试结果:
笔记而已。。。代码跟着黑马程序员写的