mapwritable用新添加的密钥替换所有现有密钥-hadoopmapreduce2.6.4

2j4z5cfb  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(315)

我正在使用hadoop2.6.4,并尝试实现一个用于单词共现的条纹Map器。我在尝试使用时遇到问题 MapWritable 班级。当尝试向Map中添加新的键/值时,添加的任何键都将用自身替换Map中的其他每个键。
例如,假设我有一个句子像“这是一个有两个a字母的句子”
第一遍,我在看单词“this”的共现。所以预期的Map器是

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

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

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

我创建了一个方法来转换 HashMapMapWritable ,这就是问题所在。这是我正在使用的代码。我添加了print语句,以确保我添加的值是正确的(它们是正确的),然后我打印键以查看添加它们时发生了什么。在这里,我可以看到它正在替换每个键,因为它添加了一个新的键。
根据我看过的所有文档,我正在使用 MapWritable.put() 它应该简单地添加到Map或更新值,就像使用泛型 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;
}
ukdjmx9f

ukdjmx9f1#

您反复调用key.set(),只分配了一个文本。这基本上就是你在做的。

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"));

相关问题