[英]Hadoop MR hold array reference in reduce method
我想有一個arrayList,它在reduce函數中保存對象的引用。
@Override
public void reduce( final Text pKey,
final Iterable<BSONWritable> pValues,
final Context pContext )
throws IOException, InterruptedException{
final ArrayList<BSONWritable> bsonObjects = new ArrayList<BSONWritable>();
for ( final BSONWritable value : pValues ){
bsonObjects.add(value);
//do some calculations.
}
for ( final BSONWritable value : bsonObjects ){
//do something else.
}
}
問題是bsonObjects.size()返回正確數量的元素,但列表的所有元素都等於最后插入的元素。 例如,如果
{ID:1}
{ID:2}
{ID:3}
要插入的元素bsonObjects將包含3個項目,但所有這些項目都將是{id:3}。 這種方法有問題嗎? 知道為什么會這樣嗎? 我試圖將List更改為Map,但之后只有一個元素被添加到地圖中。 此外,我試圖將bsonObject的聲明更改為全局,但同樣的行為發生。
這是記錄在案的行為。 原因是pValues Iterator重新使用BSONWritable實例,當它在循環中的值發生變化時,bsonObjects ArrayList中的所有引用也會更新。 在bsonObjects上調用add()時,您正在存儲引用。 這種方法允許Hadoop節省內存。
您應該在第一個循環中實例化一個新的BSONWritable變量,該變量等於變量值(深拷貝)。 然后將新變量添加到bsonObjects中。
嘗試這個:
for ( final BSONWritable value : pValues ){
BSONWritable v = value;
bsonObjects.add(v);
//do some calculations.
}
for ( final BSONWritable value : bsonObjects ){
//do something else.
}
然后,您將能夠在第二個循環中迭代bsonObjects並檢索每個不同的值。
但是,您還應該小心 - 如果您進行深度復制,則此縮減器中的鍵的所有值都需要適合內存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.