您好我在reducer中执行一些计算并尝试将数据加载到ArrayList中。当我在稍后的代码点对ArrayList执行get操作时,ArrayList中的所有对象都具有相同的值。
public ArrayList<some_class> temp = new ArrayList<some_class>();
//This is global variable
@Override
public void reduce(Key_class key, Iterator<some_class> values,
OutputCollector<Text, Text> output, Reporter reporter)
throws IOException {
if(this.output==null){
this.output=output;
}
while(values.hasNext())
{
//if i print here
//and do the following values.next().val1
//I'm getting the right result
temp.add(values.next());
}
System.out.println(temp.get(0).val1);//Wrong result
}
我的输出如下: 12/10/2012 10:13 12/10/2012 10:13
实际输出应为: 12/10/2012 09:10 12/10/2012 10:13
感谢您的帮助。感谢!!!
答案 0 :(得分:4)
值的实施是什么?出现症状的一个原因是,如果values.mext()始终返回对同一对象的引用,但会更改该对象的值以匹配迭代中的下一个项目。如果您无权访问其源代码,则可以通过在循环内打印value.next()结果的System.identityHashCode()来测试此条件。
如果这是正在发生的事情,您需要修复Iterator的实现以每次返回一个不同的对象,或者您需要在添加到ArrayList之前克隆该对象。
答案 1 :(得分:2)
就像@Patricia Shanahan已经注意到的那样,对象正在被重用 - 对象的底层内容正在被更新(但是所有子对象等也被重用,这取决于你的readFields / write方法)
在将对象添加到ArrayList之前,您可以解决这些对象的复制:
@Override
public void reduce(Key_class key, Iterator<some_class> values,
OutputCollector<Text, Text> output, Reporter reporter)
throws IOException {
if(this.output==null){
this.output=output;
}
// you should out the arraylist to avoid unexpected behaviour and OOME
temp.clear();
while(values.hasNext())
{
// you'll need a copy of the configuration - conf
temp.add(
ReflectionUtils.copy(conf, values.next(), new some_class()));
}
}