我的映射器类将输出键值对,例如:
abc 1
abc 2
abc 1
我想使用
HashMap
合并值并计算化简器类中同一对的出现,输出如下:abc 1:2 2:1
但是我的输出结果是:
abc 1:2:1 2:1:1
感觉还有其他字符串与输出串联在一起,但是我不知道为什么。
这是我的代码:
Text combiner = new Text();
StringBuilder strBuilder = new StringBuilder();
@Override
public void reduce(Text key, Iterable<Text> values,
Context context
) throws IOException, InterruptedException {
HashMap<Text, Integer> result = new HashMap<Text, Integer>();
for (Text val : values) {
if(result.containsKey(val)){
int newVal = result.get(val) + 1;
result.put(val, newVal);
}else{
result.put(val, 1);
}
}
for(Map.Entry<Text, Integer> entry: result.entrySet()){
strBuilder.append(entry.getKey().toString());
strBuilder.append(":");
strBuilder.append(entry.getValue());
strBuilder.append("\t");
}
combiner.set(strBuilder.toString());
context.write(key, combiner);
}
最佳答案
我测试了这段代码,看起来还不错。之所以会得到这样的输出,最可能的原因是因为您也正在将此 reducer 作为组合器运行,这可以解释为什么要获得三个值。合并执行第一个串联,然后执行reduce进行第二个串联。
您需要确保在作业设置中未配置组合器。
我还建议您更改代码,以确保将新版本的Text
值存储在HashMap中,请记住Hadoop将重用这些对象。因此,您实际上应该做的是:result.put(new Text(val), newVal);
或更改HashMap来存储字符串,这是安全的,因为它们是不可变的。
关于java - 在Hadoop Reducer中合并str值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46840302/