这个很简单哈,编程的版本很多种。

代码版本1

 package zhouls.bigdata.myMapReduce.wordcount5;

 import java.io.IOException;
import java.util.StringTokenizer;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class WordCount
{
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
} public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
} public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
// FileInputFormat.addInputPath(job, new Path("hdfs:/HadoopMaster:9000/wc.txt"));
// FileOutputFormat.setOutputPath(job, new Path("hdfs:/HadoopMaster:9000/out/wordcount"));
FileInputFormat.addInputPath(job, new Path("./data/wc.txt"));
FileOutputFormat.setOutputPath(job, new Path("./out/WordCount"));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}

代码版本3

 package com.dajiangtai.Hadoop.MapReduce;

 import java.io.IOException;
import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; @SuppressWarnings("unused")
public class WordCount {//2017最新详解版 public static class TokenizerMapper extends
Mapper<Object, Text, Text, IntWritable>
// 为什么这里k1要用Object、Text、IntWritable等,而不是java的string啊、int啊类型,当然,你可以用其他的,这样用的好处是,因为它里面实现了序列化和反序列化。
// 可以让在节点间传输和通信效率更高。这就为什么hadoop本身的机制类型的诞生。 //这个Mapper类是一个泛型类型,它有四个形参类型,分别指定map函数的输入键、输入值、输出键、输出值的类型。hadoop没有直接使用Java内嵌的类型,而是自己开发了一套可以优化网络序列化传输的基本类型。这些类型都在org.apache.hadoop.io包中。
//比如这个例子中的Object类型,适用于字段需要使用多种类型的时候,Text类型相当于Java中的String类型,IntWritable类型相当于Java中的Integer类型
{
//定义两个变量或者说是定义两个对象,叫法都可以
private final static IntWritable one = new IntWritable(1);//这个1表示每个单词出现一次,map的输出value就是1.
//因为,v1是单词出现次数,直接对one赋值为1
private Text word = new Text(); public void map(Object key, Text value, Context context)
//context它是mapper的一个内部类,简单的说顶级接口是为了在map或是reduce任务中跟踪task的状态,很自然的MapContext就是记录了map执行的上下文,在mapper类中,这个context可以存储一些job conf的信息,比如job运行时参数等,我们可以在map函数中处理这个信息,这也是Hadoop中参数传递中一个很经典的例子,同时context作为了map和reduce执行中各个函数的一个桥梁,这个设计和Java web中的session对象、application对象很相似
//简单的说context对象保存了作业运行的上下文信息,比如:作业配置信息、InputSplit信息、任务ID等
//我们这里最直观的就是主要用到context的write方法。
//说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用! throws IOException, InterruptedException {
//The tokenizer uses the default delimiter set, which is " \t\n\r": the space character, the tab character, the newline character, the carriage-return character
StringTokenizer itr = new StringTokenizer(value.toString());//将Text类型的value转化成字符串类型
//StringTokenizer是字符串分隔解析类型,StringTokenizer 用来分割字符串,你可以指定分隔符,比如',',或者空格之类的字符。 //使用StringTokenizer类将字符串“hello,java,delphi,asp,PHP”分解为三个单词
// 程序的运行结果为:
// hello
// java
// delphi
// asp
//
// php while (itr.hasMoreTokens()) {//hasMoreTokens() 方法是用来测试是否有此标记生成器的字符串可用更多的标记。
// 实际上就是java.util.StringTokenizer.hasMoreTokens()
// hasMoreTokens() 方法是用来测试是否有此标记生成器的字符串可用更多的标记。
//java.util.StringTokenizer.hasMoreTokens() word.set(itr.nextToken());//nextToken()这是 StringTokenizer 类下的一个方法,nextToken() 用于返回下一个匹配的字段。
context.write(word, one);
}
}
} public static class IntSumReducer extends
Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {
//我们这里最直观的就是主要用到context的write方法。
//说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用! int sum = 0;
for (IntWritable val : values) {//叫做增强的for循环,也叫for星型循环
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
} public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();//程序里,只需写这么一句话,就会加载到hadoop的配置文件了
//Configuration类代表作业的配置,该类会加载mapred-site.xml、hdfs-site.xml、core-site.xml等配置文件。
//删除已经存在的输出目录
Path mypath = new Path("hdfs://djt002:9000/outData/wordcount");//输出路径
FileSystem hdfs = mypath.getFileSystem(conf);//程序里,只需写这么一句话,就可以获取到文件系统了。
//FileSystem里面包括很多系统,不局限于hdfs,是因为,程序读到conf,哦,原来是hadoop集群啊。这时,才认知到是hdfs //如果文件系统中存在这个输出路径,则删除掉,保证输出目录不能提前存在。
if (hdfs.isDirectory(mypath)) {
hdfs.delete(mypath, true);
} //job对象指定了作业执行规范,可以用它来控制整个作业的运行。
Job job = Job.getInstance();// new Job(conf, "word count");
job.setJarByClass(WordCount.class);//我们在hadoop集群上运行作业的时候,要把代码打包成一个jar文件,然后把这个文件
//传到集群上,然后通过命令来执行这个作业,但是命令中不必指定JAR文件的名称,在这条命令中通过job对象的setJarByClass()
//中传递一个主类就行,hadoop会通过这个主类来查找包含它的JAR文件。 job.setMapperClass(TokenizerMapper.class);
//job.setReducerClass(IntSumReducer.class);
job.setCombinerClass(IntSumReducer.class);//Combiner最终不能影响reduce输出的结果
// 这句话要好好理解!!! job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
//一般情况下mapper和reducer的输出的数据类型是一样的,所以我们用上面两条命令就行,如果不一样,我们就可以用下面两条命令单独指定mapper的输出key、value的数据类型
//job.setMapOutputKeyClass(Text.class);
//job.setMapOutputValueClass(IntWritable.class);
//hadoop默认的是TextInputFormat和TextOutputFormat,所以说我们这里可以不用配置。
//job.setInputFormatClass(TextInputFormat.class);
//job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPath(job, new Path(
"hdfs://djt002:9000/inputData/wordcount/wc.txt"));//FileInputFormat.addInputPath()指定的这个路径可以是单个文件、一个目录或符合特定文件模式的一系列文件。
//从方法名称可以看出,可以通过多次调用这个方法来实现多路径的输入。
FileOutputFormat.setOutputPath(job, new Path(
"hdfs://djt002:9000/outData/wordcount"));//只能有一个输出路径,该路径指定的就是reduce函数输出文件的写入目录。
//特别注意:输出目录不能提前存在,否则hadoop会报错并拒绝执行作业,这样做的目的是防止数据丢失,因为长时间运行的作业如果结果被意外覆盖掉,那肯定不是我们想要的
System.exit(job.waitForCompletion(true) ? 0 : 1);
//使用job.waitForCompletion()提交作业并等待执行完成,该方法返回一个boolean值,表示执行成功或者失败,这个布尔值被转换成程序退出代码0或1,该布尔参数还是一个详细标识,所以作业会把进度写到控制台。
//waitForCompletion()提交作业后,每秒会轮询作业的进度,如果发现和上次报告后有改变,就把进度报告到控制台,作业完成后,如果成功就显示作业计数器,如果失败则把导致作业失败的错误输出到控制台
}
} //TextInputFormat是hadoop默认的输入格式,这个类继承自FileInputFormat,使用这种输入格式,每个文件都会单独作为Map的输入,每行数据都会生成一条记录,每条记录会表示成<key,value>的形式。
//key的值是每条数据记录在数据分片中的字节偏移量,数据类型是LongWritable.
//value的值为每行的内容,数据类型为Text。
//
//实际上InputFormat()是用来生成可供Map处理的<key,value>的。
//InputSplit是hadoop中用来把输入数据传送给每个单独的Map(也就是我们常说的一个split对应一个Map),
//InputSplit存储的并非数据本身,而是一个分片长度和一个记录数据位置的数组。
//生成InputSplit的方法可以通过InputFormat()来设置。
//当数据传给Map时,Map会将输入分片传送给InputFormat(),InputFormat()则调用getRecordReader()生成RecordReader,RecordReader则再通过creatKey()和creatValue()创建可供Map处理的<key,value>对。
//
//OutputFormat()
//默认的输出格式为TextOutputFormat。它和默认输入格式类似,会将每条记录以一行的形式存入文本文件。它的键和值可以是任意形式的,因为程序内部会调用toString()将键和值转化为String类型再输出。

 代码版本2

 package zhouls.bigdata.myMapReduce.wordcount5;

 import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner; public class WordCount implements Tool
{
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1);
private Text word = new Text(); public void map(Object key, Text value, Context context
) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
} public static class IntSumReducer
extends Reducer<Text,IntWritable,Text,IntWritable> {
private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values,
Context context
) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
} public int run(String[] arg0) throws Exception {
Configuration conf = new Configuration();
//2删除已经存在的输出目录
Path mypath = new Path(arg0[1]);//下标为1,即是输出路径
FileSystem hdfs = mypath.getFileSystem(conf);//获取文件系统
if (hdfs.isDirectory(mypath))
{//如果文件系统中存在这个输出路径,则删除掉
hdfs.delete(mypath, true);
} Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(arg0[0]));// 文件输入路径
FileOutputFormat.setOutputPath(job, new Path(arg0[1]));// 文件输出路径
job.waitForCompletion(true); return 0; } public static void main(String[] args) throws Exception { //集群路径
// String[] args0 = { "hdfs:/HadoopMaster:9000/wc.txt",
// "hdfs:/HadoopMaster:9000/out/wordcount"}; //本地路径
String[] args0 = { "./data/wc.txt",
"./out/WordCount"};
int ec = ToolRunner.run( new Configuration(), new WordCount(), args0);
System. exit(ec);
} @Override
public Configuration getConf() {
// TODO Auto-generated method stub
return null;
} @Override
public void setConf(Configuration arg0) {
// TODO Auto-generated method stub }
}                                                                                             

Hadoop MapReduce编程 API入门系列之wordcount版本1(五)的更多相关文章

  1. Hadoop MapReduce编程 API入门系列之wordcount版本4(八)

    这篇博客,给大家,体会不一样的版本编程. 是将map.combiner.shuffle.reduce等分开放一个.java里.则需要实现Tool. 代码 package zhouls.bigdata. ...

  2. Hadoop MapReduce编程 API入门系列之wordcount版本5(九)

    这篇博客,给大家,体会不一样的版本编程. 代码 package zhouls.bigdata.myMapReduce.wordcount1; import java.io.IOException; i ...

  3. Hadoop MapReduce编程 API入门系列之wordcount版本3(七)

    这篇博客,给大家,体会不一样的版本编程. 代码 package zhouls.bigdata.myMapReduce.wordcount3; import java.io.IOException; i ...

  4. Hadoop MapReduce编程 API入门系列之wordcount版本2(六)

    这篇博客,给大家,体会不一样的版本编程. 代码 package zhouls.bigdata.myMapReduce.wordcount4; import java.io.IOException; i ...

  5. Hadoop MapReduce编程 API入门系列之最短路径(十五)

    不多说,直接上代码. ======================================= Iteration: 1= Input path: out/shortestpath/input. ...

  6. Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)

    不多说,直接上代码. Hadoop MapReduce编程 API入门系列之小文件合并(二十九) 生成的结果,作为输入源. 代码 package zhouls.bigdata.myMapReduce. ...

  7. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本3(九)

    不多说,直接上干货! 下面,是版本1. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本1(一) 下面是版本2. Hadoop MapReduce编程 API入门系列之挖掘气象数 ...

  8. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本2(十)

    下面,是版本1. Hadoop MapReduce编程 API入门系列之挖掘气象数据版本1(一) 这篇博文,包括了,实际生产开发非常重要的,单元测试和调试代码.这里不多赘述,直接送上代码. MRUni ...

  9. Hadoop MapReduce编程 API入门系列之join(二十六)(未完)

    不多说,直接上代码. 天气记录数据库 Station ID Timestamp Temperature 气象站数据库 Station ID Station Name 气象站和天气记录合并之后的示意图如 ...

随机推荐

  1. 关于java中的继承

    我们都知道Java中的继承是复用代码.扩展子类的一种方式,继承使得Java中重复的代码能够被提取出来供子类共用,对于Java程序的性能以及修改和扩展有很大的意义,所以这是一个非常重要的知识点. 那么对 ...

  2. eas中删除原来的监听事件添加新的监听事件

    kdtEntrys.removeKDTEditListener(kdtEntrys.getListeners(KDTEditListener.class)[0]);  kdtEntrys.addKDT ...

  3. php curl选项列表(超详细)

    第一类:对于下面的这些option的可选参数,value应该被设置一个bool类型的值:选项可选value值备注 CURLOPT_AUTOREFERER当根据Location:重定向时,自动设置hea ...

  4. 操作符重载、继承(day08)

    二十 操作符重载 函数操作符"()" 功能:让对象当做函数来使用 注:对参数的个数.返回类型没有限制 eg: class A{...}; A a; //a.operator()(1 ...

  5. win10、win7 使用centos配置网络,可以让Xshell进行连接,虚拟机进行上网;

    系统:window 10 虚拟机VMware® Workstation 15 Pro Linux版本:CentOS-6.3 前提:关闭防火墙 如果是win7 系统可以不用第八步,如果不行可以试一下第八 ...

  6. python-if判断

    1. python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何 ...

  7. Golang - 处理字符串

    目录 Golang - 处理字符串 1. 字符串操作 2. 字符串转换 Golang - 处理字符串 1. 字符串操作 func Contains(s, substr string) bool 字符串 ...

  8. (17)Spring Boot普通类调用bean【从零开始学Spring Boot】

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用 ...

  9. 洛谷 P3183 BZOJ 4562 [HAOI2016]食物链

    题目描述 如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你n个物种和m条能量流动关系,求其中的食物链条数.物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3.... ...

  10. [bzoj1218][HNOI2003]激光炸弹_暴力

    激光炸弹 bzoj-1218 HNOI-2003 题目大意:在笛卡尔坐标系上有n个点,问一个平行于坐标轴的r*r的正方形可以最多覆盖多少个目标. 注释:$1\le n \le 10000$,$1\le ...