Hadoop实战——MapReduce对英文单词文本进行统计和排序(超详细教学,算法分析)

B站视频操作过程

Hadoop实战——对单词文本进行统计和排序_哔哩哔哩_bilibili

更多MapReduce设计案例地址

https://github.com/yuanprogrammer/MapReduce-Case-Statistics

目录

一、前提准备工作

启动hadoop集群

 windows可以访问

二、整体流程

三、核心代码讲解

四、生成jar包上传

五、运行程序

Gitee仓库Hadoop项目下载地址

其他系列技术教学、实战开发



一、前提准备工作

启动hadoop集群

必须已经成功搭建好了hadoop集群,打开主节点和子节点全部虚拟机,启动hadoop

 windows可以访问

关闭主节点虚拟机的防火墙,在windows的hosts文件添加配置信息

二、整体流程

整体流程如下

程序内部执行过程如下

 

三、核心代码讲解

Mapper类

将单词文本进行切割,切割成一个个的单词,写入到上下文中

(1)按行读取,通过split函数进行切割,将切割出来的一个个单词放到数组ars中

(2)遍历数组ars,将存在的单词数据存储到word中,然后将word写入到context上下文(使Redcue程序能访问到数据)

​​​​​​​

package com.itcast;

import java.io.IOException;
import java.util.Date;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

/**
 * FileName:    WordMapper
 * Author:      Yuan-Programmer
 * Date:        2021/11/8 23:29
 * Description:
 */
// 创建一个 WordMapper类 继承于 Mapper抽象类
public class WordMapper extends Mapper<Object, Text, Text, IntWritable> {
    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    // Mapper抽象类的核心方法,三个参数
    public void map(Object key, // 首字符偏移量
                    Text value, // 文件的一行内容
                    Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似
            throws IOException, InterruptedException {
        String[] ars = value.toString().split("['.;,?| \t\n\r\f]");
        for (String tmp : ars) {
            if (tmp == null || tmp.length() <= 0) {
                continue;
            }
            word.set(tmp);
            System.out.println(new Date().toGMTString() + ":" + word + "出现一次,计数+1");
            context.write(word, one);
        }
    }
}

Reduce类(部分代码展示)

(1)将每个单词统计次数结果进行求和合并,写入到map集合里

(2)调用Utils工具类的sortValue方法对map集合进行排序

(3)遍历排序好的map集合,依次写入到context上下文中

​​​​​​​

package com.itcast;

import java.io.IOException;
import java.util.*;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

/**
 * FileName:    WordReduce
 * Author:      Yuan-Programmer
 * Date:        2021/11/8 23:32
 * Description:
 */
// 创建一个 WordReducer类 继承于 Reducer抽象类
public class WordReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    private IntWritable result = new IntWritable(); // 用于记录 key 的最终的词频数
    HashMap<String, Integer> map = new HashMap();

    // Reducer抽象类的核心方法,三个参数
    public void reduce(Text key, // Map端 输出的 key 值
                       Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)
                       Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似
            throws IOException, InterruptedException {
        int sum = 0;
        for (IntWritable val : values) // 遍历 values集合,并把值相加
        {
            sum += val.get();
        }
        map.put(key.toString(), sum);
        System.out.println(new Date().toGMTString() + ":" + key + "出现了" + result);
    }

    @Override
    protected void cleanup(Context context) throws IOException, InterruptedException {
        //  根据map中的value进行排序
        Map<String, Integer> sortedMap = MapUtils.sortValue(map);
        Set<Map.Entry<String, Integer>> entries = sortedMap.entrySet();
        Iterator<Map.Entry<String, Integer>> it = entries.iterator();
        /**
         * 不设置count,对全部单词进行排序
         * 循环获取迭代器的Map对象,再获取对应K,V
         * 将K,V封装到上下文中
         */
        while (it.hasNext()) {
            //  获取Map
            Map.Entry<String, Integer> entry = it.next();
            String key = entry.getKey();
            Integer value = entry.getValue();
            //  封装k3,v3
            Text k3 = new Text();
            k3.set(key);
            IntWritable v3 = new IntWritable();
            v3.set(value);
            //  写入上下文
            context.write(k3, v3);
        }
    }
}

 Utils类(对map进行排序)

 (1)继承Comparable类,复写compare方法

(2)通过map<k,v>集合的value(也就是单词次数)进行排序

(3)将排序好的map返回

package com.itcast;

/**
 * FileName:    MapUtils
 * Author:      Yuan-Programmer
 * Date:        2021/11/9 0:05
 * Description:
 */

import java.util.*;

/**
 •	Map工具类
 */
public class MapUtils {
    /**
     –	根据Map的value值降序排序
     –	@param map
     –	@param@param@return
     */
    public static <K, V extends Comparable<? super V>> Map<K, V> sortValue(Map<K, V> map) {
        List<Map.Entry<K, V>> list = new ArrayList(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
            @Override
            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
                /**
                 * o1-o2:升序
                 * o2-o1:降序
                 * 返回结果加上“-”表示取反操作(升序->降序,降序->升序)
                 */
                int compare = (o1.getValue()).compareTo(o2.getValue());
                return -compare;
            }
        });

        //将排序结果返回上一级
        Map<K, V> returnMap = new LinkedHashMap<K, V>();
        for (Map.Entry<K, V> entry : list) {
            returnMap.put(entry.getKey(), entry.getValue());
        }
        return returnMap;
    }
}

新建一个测试类测试一下,可以看到排序OK

四、生成jar包上传

先点击右边的 clean 清理一下,然后点击 package 生成打包jar包

运行完毕,会在左边生成一个 target 的文件夹,展开可以看到生成jar包程序

选中jar包,右键选择复制,粘贴到桌面

 打开 winscp 工具,连接主节点虚拟机,将刚刚粘贴在桌面的jar包拷贝到虚拟机里(路径自己选,知道在哪就行)

打开虚拟机,跳转到刚刚复制的路径目录下,可以看到已经拷贝进来了

 

五、运行程序

(1)创建单词文本并上传

在下面可以看到有一个words.txt文本,这是我之前创好的

more指令查看文本,可以看到文本里有很多的英文单词

 (2)上传到HDFS文件系统

首先创建一个文件夹存放统计前的单词文本(words.txt)

 将单词文本(words.txt)上传到刚刚创建的文件夹下

 执行jar包程序,hadoop   jar   jar包名称   包名称+主类名   输入路径   输出路径

 包名称+主类名如下

回车执行命令,等待提示运行完毕,运行结束后

打开HDFS文件系统的output目录下,就能看到输出结果,打开文件点击Download下载

以文本方式打开,可以看到已经对单词进行了统计并且对其进行降序操作

Gitee仓库Hadoop项目下载地址

Gitee仓库地址:Hadoop实战项目源码集合: https://blog.csdn.net/weixin_47971206CSDN文章教学中的源码汇总集合

其他系列技术教学、实战开发

https://github.com/yuanprogrammer/MapReduce-Case-Statistics


- 本次文章分享就到这,有什么疑问或有更好的建议可在评论区留言,也可以私信我
- 感谢阅读~


  • 30
    点赞
  • 160
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
好的,这个问题可以通过编写一个 MapReduce 程序来解决。以下是一个简单的 MapReduce 程序来对 Hadoop.txt 中各个单词出现的次数进行统计的示例: 1. Map 阶段 在 Map 阶段,我们将输入文件 Hadoop.txt 中的每一行分解成单词,并将每个单词映射到一个键值对中,其中键是单词本身,值为 1,表示该单词出现了一次。 ```java public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private final static IntWritable ONE = new IntWritable(1); private Text word = new Text(); public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); StringTokenizer tokenizer = new StringTokenizer(line); while (tokenizer.hasMoreTokens()) { word.set(tokenizer.nextToken()); context.write(word, ONE); } } } ``` 2. Reduce 阶段 在 Reduce 阶段,我们将相同单词的键值对合并,并将它们的值相加,以得到每个单词出现的总次数。 ```java public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } context.write(key, new IntWritable(sum)); } } ``` 3. 驱动程序 在驱动程序中,我们指定输入输出路径,以及 Mapper 和 Reducer 类。 ```java public class WordCountDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "word count"); job.setJarByClass(WordCountDriver.class); job.setMapperClass(WordCountMapper.class); job.setCombinerClass(WordCountReducer.class); job.setReducerClass(WordCountReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` 以上代码可以将 Hadoop.txt 中各个单词出现的次数进行统计,并将结果输出到指定的输出路径中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OpenYuan开袁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值