我正在尝试调整此处找到的字数示例:http://wiki.apache.org/hadoop/WordCount因此它将求和并返回输入文件中的单词数,而不是计算每个单词的出现次数。
我尝试更改映射器类,使其不再在当前迭代中写入单词,而是为所有单词写入“Sum:”。
即替换
word.set(tokenizer.nextToken());
@class“ map ”
word.set("Sum: ");
文件的所有其余部分保持不变。
通过这种方式,我认为所有映射器输出都会到达相同的reducer,最终将“sum:”的数量相加,这最终将成为文件中的单词数。
含义而不是:
word 1
other 1
other 1
产生:
word 1
other 2
我期待的是:
Sum: 1
Sum: 1
Sum: 1
产生:
Sum: 3
相反,当我尝试运行代码时,我得到了一个非常长的映射操作,最终导致抛出异常:
运行时异常:java.io.IOException:溢出失败
无论输入文件有多小。
期待您的帮助。 谢谢
最佳答案
你有一个无限循环。在您的代码中,您需要调用
tokenizer.nextToken()
实际上将 StringTokenizer 从该行推进一个字。否则你的映射操作将永远不会取得进展。
所以你需要这样的东西:
public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text sumText = new Text("Sum: ");
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
tokenizer.nextToken(); //go to next word
context.write(sumText, one);
}
}
}
但是,有一个更好的没有循环的解决方案。您可以使用ẗhe countTokens()
StringTokenizer 的方法:
public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> {
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
context.write(new Text("Sum: "), new IntWritable(tokenizer.countTokens()));
}
}
关于java - Hadoop Java 字数统计调整不起作用 - 尝试对所有内容进行求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25227879/