如何将 reducer class 中的值添加到数组列表(Hadoop)中?

How to add values in reducer class into an arraylist (Hadoop)?

我的映射器输出:

1504652886  Geography
8904209587  Science
8904209587  Math
9341024668  English9
9341024668  Science

我正在尝试编写一个 reducer class,它将组合公共键并生成如下所示的输出:

1504652886  Geography
8904209587  Science, Math
9341024668  English9, Science

在 reducer class 中,我试图制作一个包含特定 ID 的所有课程的数组列表,但我肯定做错了什么。我的代码如下:

public static class Reduce extends Reducer<Text, Text, Text, Text> {

    @Override 
    public void reduce(Text key, Iterable<Text> values, Context context)
    throws IOException, InterruptedException {
        ArrayList<String> courses = new ArrayList<String>();
        for(Text x : values)
        {
            courses.add((Text) x);
        }
    }      
}

但我遗漏了一些东西并收到错误:

The method add(String) in the type ArrayList<String> is not applicable for the arguments (Text)

谁能告诉我如何获得输出?

Hadoop 的 Text class 有一个 toString() 方法,该方法 returns 此对象的字符串表示形式。所以可以只替换代码中的以下内容:

for(Text x : values)
{
    courses.add(x.toString());
}

然后,您需要将 ArrayList 转换回 Text,以便将其作为键发出。

您还缺少实际发出输出的 write() 方法。

您可以改用 StringBuilder,这应该比使用 ArrayList 更快:

public static class Reduce extends Reducer<Text, Text, Text, Text> {

    Text valueToEmit = new Text();

    public void reduce(Text key, Iterable<Text> values, Context context)
    throws IOException, InterruptedException {
        StringBuilder sb = new StringBuilder();
        for(Text x : values)
        {
            sb.append(x.toString()).append(",");
        }

        valueToEmit.set(sb.substring(0,sb.length()-1)); //to remove the last ','
        context.write(key, valueToEmit);
    } 
}