①map函数的具体逻辑代码在重写的map()中实现
WordCountMapper.java
package com.igeekhome.mapreduce.wordcount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* LongWritable:代表map函数的输入KV键值对的key类型,值为每行文本的偏移量
* 第一个Text:代表map函数的输入KV键值对的Value类型,值为每行文本
*
* 第二个Text:代表map函数的输出KV键值对的key类型,代表每个单词
* IntWritable:代表map函数的输出KV键值对的Value类型,代表每个单词出现的次数(1次)
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>{
//新建Text对象,该对象作为map阶段输出的kv键值对中的key
Text KeyOut = new Text();
//新建IntWritable对象,该对象作为map阶段输出的kv键值对中的value
IntWritable valueOut =new IntWritable(1);
//map函数的具体逻辑代码在重写的map()中实现
//文本中的每一行就会会调用一次map()方法
@Override
protected void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException {
//获取一行文本
String line = value.toString();
//根据单词的分隔符对于单词进行拆分(空格)
String[] words = line.split(" ");
//对数组进行遍历
for (String word : words){
//对输出Kv中的key进行赋值
KeyOut.set(word);
//map阶段处理完成,进行kv键值对的输出
context.write(KeyOut,valueOut);
}
}
}
② reduce函数的具体逻辑代码在重写的reduce()中实现
WordCountRedecer.java
package com.igeekhome.mapreduce.wordcount;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* 第一个Text:reduce阶段输入的kv键值对中的key,实际上也是map阶段输出的kv键值对中的key,值为单词
* 第一个IntWritable:reduce阶段输入的kv键值对中的value,实际上也是map阶段输出的kv键值对中的value,值为1
*
* 第二个Text:reduce阶段输出的kv键值对中的key,值为单词
* 第二个IntWritable:reduce阶段输出的kv键值对中的value,值为对应的单词在整个文本中出现的总次数
*/
public class WordCountReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
//新建IntWritable对象 作为reduce阶段输出的kv键值对中的value
IntWritable valueOut=new IntWritable();
//reduce函数的具体逻辑代码在重写的reduce()中实现
@Override
protected void reduce(Text key,Iterable<IntWritable> values, Context context) throws IOException,InterruptedException{
//定义单词出现的总次数
int totalCount = 0;
//对单词出现的次数进行累加
for(IntWritable value : values){
//totalCount = totalCount + value.get()
totalCount += value.get();
}
//对reduce阶段输出的value进行赋值
valueOut.set(totalCount);
//reduce阶段统计完成,将结果进行输出
context.write(key,valueOut);
}
}
③作为整个mapreduce程序的入口,进行相关程序参数的设置
WordCountDriver.java
package com.igeekhome.mapreduce.wordcount;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
//作为整个mapreduce程序的入口,进行相关程序参数的设置
public class WordCountDriver {
public static void main(String[] arg) throws IOException, InterruptedException, ClassNotFoundException {
//1.获取配置信息对象和job对象
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
//2.关联Driver类
job.setJarByClass(WordCountDriver.class);
//3.设置mapper和reducer的类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);
//4.设置mapper输出的kv类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//5.设置最终输出的kv类型(reducer输出类型)
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//6.设置文件的输入逻辑和计算结果的输出路径
//要计算的文件路径
Path filePath1 = new Path("D:\\大数据实践\\words.txt");
Path filePath2 = new Path("D:\\大数据实践\\words2.txt");
FileInputFormat.setInputPaths(job,filePath1,filePath2);
//设置计算结果的输出路径
Path outputPath =new Path("D:\\大数据实践\\wordcount_output");
FileOutputFormat.setOutputPath(job,outputPath);
//7.提交任务,进行计算
boolean result = job.waitForCompletion(true);
System.out.println(result ? "任务执行成功":"任务执行失败");
}
}
(注意不要导错包)
运行结果
words.txt
words2.txt