MapReduce Hadoop StringTokenizer 获取 NoSuchElementException

Posted

技术标签:

【中文标题】MapReduce Hadoop StringTokenizer 获取 NoSuchElementException【英文标题】:MapReduce Hadoop StringTokenizer getting NoSuchElementException 【发布时间】:2016-02-14 10:45:01 【问题描述】:

我正在尝试使用 wordcount 的输出文件作为 MapReduce 的输入文件,该文件将显示每个计数有多少(有多少单词出现一次、两次、三次等)。

我想使用每个单词的计数作为键,1 作为值,跳过单词本身。

如果输入文件是这样的:

422 苹果 3 水果 2 大猩猩 9 猴子 3 斑马 12

输出应该是:

2 1 3 2 9 1 12 1

使用StringTokenizer分解文件,下面map函数中的nextToken()给出NoSuchElementException

public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>

    private final static IntWritable one = new IntWritable(1);
    private Text count = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException 
        StringTokenizer itr = new StringTokenizer(value.toString());
        itr.nextToken(); // Skip over first line, which has just one element
        while (itr.hasMoreTokens()) 
            itr.nextToken(); // Skip over word
            count.set(itr.nextToken()); // save count as key
            context.write(count, one);
        
    
  

我不确定为什么或如何解决它?

【问题讨论】:

如果你的输入模式总是像apple 3,你为什么不使用String#split方法得到String[] elems两个元素,然后使用elems[1]作为伯爵? joanne 看看我的回答是否解决了您的问题。如果是这样,您可以将其标记为已接受,否则,请让我们知道问题是否仍然存在或者您是否遇到了新的错误,请按照我们的建议。 【参考方案1】:

欢迎来到 *** joanne 和 MapReduce 编程!

我猜原因是你总是跳过第一个令牌并要求接下来的两个。您对 每一 行都这样做。

请记住,从第 1 行开始,到第 2 行,地图对输入的不同部分并行运行,而不是按顺序运行。每次,StringTokenizer 仅针对一行调用,而不是整个输入. 话虽如此,您的问题的解决方案如下:

public void map(Object key, Text value, Context context) throws IOException, InterruptedException 
    StringTokenizer itr = new StringTokenizer(value.toString()); // each time the value is a different line
    if (itr.countTokens() == 2)  //this skips the first line and other lines that possible contain one word
        itr.nextToken(); // Skip over word
        count.set(itr.nextToken()); // save count as key
        context.write(count, one);
    

PS1:您也可以使用String.split() 方法,但这取决于您。

PS2:您也可以考虑根据您的数据和要求将密钥写为IntWritableVIntWritable(将字符串解析为 int 的速度较慢,但​​传输到网络的速度较快和更低的内存消耗)。

【讨论】:

以上是关于MapReduce Hadoop StringTokenizer 获取 NoSuchElementException的主要内容,如果未能解决你的问题,请参考以下文章

hadoop和mapreduce是一种啥关系?

hadoop mapreduce 分桶

Big Data - Hadoop - MapReduce初学Hadoop之图解MapReduce与WordCount示例分析

Hadoop-MapReduce

Hadoop-MapReduce

学习笔记Hadoop—— Hadoop基础操作—— MapReduce常用Shell操作MapReduce任务管理