我在完成一项我认为很简单的任务时遇到了一些麻烦。我试图迭代一个文件与两个int每行。目标是将第一个整数用作键值,并将第二个整数的值存储为列表,但前提是该值不存在于列表中。因此,如果文件看起来像这样:
3 11
4 7
5 10
5 6
6 5
6 10
3 11 #should be ignored
那么理想情况下,我应该在结尾有这样的内容:
3 [11]
4 [7]
5 [10, 6]
6 [5, 10]
从存储值的数据结构来看,最好的方法是什么?我知道我可以使用ArrayWritable,但我不认为你可以动态地给它添加值。我不关心键的顺序。
所以你的问题与经典的WordCount例子非常相似。在您的例子中,您不想发出总和,而只想发出一次值。至于数据结构本身,它已经在一个数据结构Iterable中,因此没有必要将它们添加到新的数据结构中。你真正需要做的就是把它们以你需要的任何形式打印出来。下面我将解释我认为整个程序需要什么。
对于您想要标识映射器的映射器,您想要准确地输出键值对,就像您读取它一样。这可以使用Identity Mapper来完成,或者如果您使用新的API 0.23+,则只需不指定一个。
对于Reducer,您应该做以下类似的事情。这只是用您想要的逗号附加给定键的值,正如我之前提到的,您不需要将它们放入新的数据结构中,因为它们已经在一个数据结构中了。一旦reducer完成了键值的附加,那么它就会简单地发出带有逗号分隔值的键。
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Text value: values){
if (!first) sb.append(", ");
else first = false;
sb.append(value);
}
context.write(key, new Text(sb.toString()));
}