尝试全部求和

xoefb8l8  于 2021-06-04  发布在  Hadoop
关注(0)|答案(1)|浏览(335)

我正在尝试调整这里的wordcount示例:http://wiki.apache.org/hadoop/wordcount 因此,它将求和并返回输入文件中的字数,而不是计算每个单词的出现次数。
我试着改变mapper类的方式,使它不会在当前迭代中编写单词,而是为所有单词编写“sum:”。
i、 e.更换

  1. word.set(tokenizer.nextToken());

@类“map”与

  1. word.set("Sum: ");

文件的其余部分保持不变。
以这种方式,我认为所有Map器的输出都会得到同一个缩减器,最终将“sum:”的数量相加,这最终将是文件中的字数。
意思不是:

  1. word 1
  2. other 1
  3. other 1

这就产生了:

  1. word 1
  2. other 2

我本以为会有:

  1. Sum: 1
  2. Sum: 1
  3. Sum: 1

这就产生了:

  1. Sum: 3

相反,当我尝试运行代码时,我得到一个非常长的Map操作,最终抛出一个exeption:
runtimeexception:java.io.ioexception:溢出失败
不管输入文件有多小。
期待您的帮助。谢谢您

gywdnpxw

gywdnpxw1#

你有一个无尽的循环。在你的代码里,你需要

  1. tokenizer.nextToken()

将stringtokenizer从行中向前推进一个单词。否则,Map操作将永远不会取得进展。
所以你需要这样的东西:

  1. public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
  2. private final static IntWritable one = new IntWritable(1);
  3. private Text sumText = new Text("Sum: ");
  4. public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  5. String line = value.toString();
  6. StringTokenizer tokenizer = new StringTokenizer(line);
  7. while (tokenizer.hasMoreTokens()) {
  8. tokenizer.nextToken(); //go to next word
  9. context.write(sumText, one);
  10. }
  11. }
  12. }

但是,没有循环还有更好的解决方案。你可以用ẗ他 countTokens() stringtokenizer的方法:

  1. public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
  2. public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  3. String line = value.toString();
  4. StringTokenizer tokenizer = new StringTokenizer(line);
  5. context.write(new Text("Sum: "), new IntWritable(tokenizer.countTokens()));
  6. }
  7. }
展开查看全部

相关问题