您的位置:首页 > 运维架构

Hadoop提供的reduce函数中Iterable 接口只能遍历一次的问题

2014-05-18 17:00 316 查看
今天在写MapReduce中的reduce函数时,碰到个问题,特此记录一下:

void reduce(key, Iterable<*>values,...)

{

for(* v:values)

{

//做第一遍遍历

}

for(* v:values)

{

//做第二遍遍历

}

}

以上代码本以为可以直接通过,但是问题却出现了,就是在第二遍遍历的时候,遍历为空,这也就是说系统给reduce提供的iterable不能多次遍历。

但通过如下的代码片段却发现:

....

List<*> list = ArrayList<*>();

for(* t : list)

{

//第一遍遍历

}

for(*t : list)

{

//第二遍遍历

}

以上代码完全没有问题,因此这也就对刚才的问题提出了一个解决思路,即 先通过一边的遍历将所有内容保存到一个List中,之后再一遍一遍的边这个List即可解决 问题了。

加入ArrayList里面的应该是 新的引用,比如

list.add(new Text(value))

如下代码

public void reduce(IntWritable key, Iterable<MatrixElements> values,
Context context) throws IOException, InterruptedException {
List<MatrixElements> matrixAs = new LinkedList<MatrixElements>();
List<MatrixElements> matrixBs = new LinkedList<MatrixElements>();

for(MatrixElements e : values){
System.out.println("In Reduce: " + key + "\t" + e.toString());
if(e.type.equals("matrixA")){
matrixAs.add(e);
}else if(e.type.equals("matrixB")){
matrixBs.add(e);
}
}
// test
for(MatrixElements e : matrixAs){
System.out.println("In MatrixA: " + e.toString());
}

for(MatrixElements e : matrixBs){
System.out.println("In MatrixB: " + e.toString());
}
// end test
...

}
输出结果为

In Reduce: 0 matrixB:0-1 88.0

In Reduce: 0 matrixB:0-3 15.0

In Reduce: 0 matrixB:0-3 43.0

In Reduce: 0 matrixB:0-0 12.0

In Reduce: 0 matrixB:0-2 3.0

In Reduce: 0 matrixB:0-3 26.0

In Reduce: 0 matrixA:2-0 52.0

In Reduce: 0 matrixA:1-0 62.0

In MatrixA: matrixA:1-0 62.0

In MatrixA: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0

In MatrixB: matrixA:1-0 62.0


可以看到应用e一直指向一个特定的对象,
将matrixAs.add(e); 改为matrixAs.add(new MatrixElements(e));结果正常
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: