MapWritable用新添加的键替换所有现有键 - Hadoop MapReduce 2.6.4

时间:2017-04-22 00:33:19

标签: java hadoop dictionary hashmap

我正在使用Hadoop 2.6.4,我正在尝试为单词Co-Occurances实现Stripes映射器。我在尝试使用MapWritable课时遇到了问题。尝试将新的键/值添加到地图中时,添加的任何键都会替换地图中的每个其他键。

例如,假设我有一句话 “这是一个有两个字母的句子”

第一次尝试,我正在查看“This”这个词的共同出现。所以预期的映射器将是

<is,1>
<a,2>
<sentence,1>
<with,1>
<two,1>
<letters,1>

但实际发生的是在每次添加后续单词的迭代中,所有键/值都被替换为添加的最后一个键。我看到的实际结果如下。

<letters,1>
<letters,1>
<letters,1>
<letters,1>
<letters,1>
<letters,1>

我创建了一种将HashMap转换为MapWritable的方法,这就是问题发生的地方。这是我正在使用的代码。我添加了print语句以确保我添加的值是正确的(它们是)然后我打印键以查看正在添加它们时发生的情况。这是我能够看到它正在替换每个键,因为它添加了一个新键。

根据我查看的所有文档,我正在使用MapWritable.put(),它应该只是添加到地图或更新值,就像使用通用HashMap一样。我对导致这种情况的原因感到茫然。

public static MapWritable toMapWritable(HashMap<String,Integer> map){

  MapWritable mw = new MapWritable();
  Text key = new Text();
  IntWritable val = new IntWritable();

  for(String it : map.keySet()){
      key.set(it.toString());
      System.out.println("Setting Key: " + key.toString());
      val.set(map.get(it));
      System.out.println("Setting Value: " + map.get(key.toString()));
      mw.put(key,val);
      for(Writable itw : mw.keySet()){
          System.out.println("Actual mw Key " + itw.toString());
      }
  }

  return mw;
}

1 个答案:

答案 0 :(得分:0)

您反复调用key.set()并且只分配了一个Text。这基本上就是你在做的事情。

Text key = new Text();
key.set("key1");
key.set("key2");
System.out.println(key); // prints 'key2'

我相信您可能正在实施在Map / Reduce作业中重用对象的常见模式。但是,这取决于调用context.write()。例如:

private Text word = new Text();
private IntWritable count = new IntWritable(1);

public void map(LongWritable offset, Text line, Context context) {
  for (String s : line.toString().split(" ")) {
    word.set(s);
    context.write(word, count); // Text gets serialized here
  }
}

在上面的示例中,Map / Reduce框架将该文本序列化为字节并将其保存在幕后。这就是为什么你可以自由重用Text对象的原因。但是,MapWritable并没有做同样的事情。您需要每次都创建新密钥。

MapWritable mw = new MapWritable();
mw.put(new Text("key1"), new Text("value1"));
mw.put(new Text("key2"), new Text("value2"));