私は単純なバイグラム(単語ペア)カウントを試しています。単純な「ペア」アプローチで試しましたが、今は「ストライプ」アプローチを試すように変更しましたが、マッパーのクリーンアップルーチンでは、どういうわけか私のすべてのキーは同じ単語ペアです(最後の単語ペアのように!) と数です。
たとえば、テキスト入力は次のとおりです。
私の名前はフーです。Foo は Hadoop の新機能です。
マッパーでは、ハッシュマップは次のようになります。
((my, name), 1), ((name, is), 1), ((is, foo), 2), ((is, new), 1), ((new, to), 1), ((to, hadoop), 1)
しかし、クリーンアップルーチンで、同じハッシュマップを印刷しようとしましたが、次のようになります
((to, hadoop), 1), ((to, hadoop), 1), ((to, hadoop), 2), ((to, hadoop), 1), ((to, hadoop), 1), ((to, hadoop), 1)
私のコードは次のようになります:
Map Class:
private HashMap<TextPair, Integer> h = new HashMap<TextPair, Integer>();;
void map(...) :
...
StringTokenizer itr = new StringTokenizer(value.toString());
left = itr.nextToken();
while(itr.hasMoreTokens()) {
right = itr.nextToken();
if(left != null && right!= null) {
**//I have to create new TextPair(key object) each time!**
key.set(new Text(left.toLowerCase()), new Text(right.toLowerCase()));
//If key is there, just do count + 1 else add key with value 1
if(h.containsKey(key)) {
int total = h.get(key) + 1;
h.put(key, total);
} else {
System.out.println("key: "+ key.toString()+ " => 1");
h.put(key, 1);
}
//context.write(key, one);
}
left = right;
}
....
void cleanup(...):
Iterator<Entry<TextPair, Integer>> itr = h.entrySet().iterator();
while(itr.hasNext()) {
Entry<TextPair, Integer> entry = itr.next();
TextPair key = entry.getKey();
int total = entry.getValue().intValue();
System.out.println("--- MAP CLEANUP ---: key: "+ key.toString() + " => Total: "+ total);
context.write(key, new IntWritable(total));
}
...
注: TextPair は、私のカスタム キー クラスです。なにか提案を?
編集1:
すべてのマップタスクが完了した後、最後に実行されるマップのクリーンアップルーチンはありますか? そして、ハッシュは一種の「グローバル」です。それまたは私のイテレータに何か問題がありますか?
編集2:
ハッシュする前に map() の各反復で新しい TextPair Key オブジェクトを作成する必要があります。私はPythonでハッシュを何度も使用しましたが、それは良いことであり、苦痛ではありません。なぜ毎回新しいオブジェクトを作成する必要があるのか わかりません。