簡體   English   中英

Hadoop MR在reduce方法中保存數組引用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM