gpt4 book ai didi

java - Hadoop MR 在 reduce 方法中保持数组引用

转载 作者:可可西里 更新时间:2023-11-01 16:34:28 27 4
gpt4 key购买 nike

我想要一个 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}。这种方法有问题吗?知道为什么会这样吗?我试图将列表更改为 map ,但随后只有一个元素被添加到 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 并检索每个不同的值。

但是,您也应该小心——如果您进行深度复制,则此 reducer 中键的所有值都需要放入内存中。

关于java - Hadoop MR 在 reduce 方法中保持数组引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11005496/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com