我正在编写一个map reduce应用程序scala。直到地图功能一切正常。但是在编写减速机时我遇到了问题。
override def reduce(key: Text, values: java.lang.Iterable[Text],
context: ReducerContext) {
}
ReducerContext
被定义为指向上下文内部类,所以我在这里很好。
问题在于Iterable
(Java)组件。我无法遍历它。
我明白,首先我将它转换为scala Iterable
,然后迭代它,我也做了但仍然没有得到结果。
我已经尝试了scala.collection.JavaConverters._和JavaConversions._ 这里有一些没有成功的scanarios
val jit: java.util.Iterator[Text]= values.iterator()
val abc = JavaConversions.asScalaIterator(jit) /// val abc=jit.asScala
println("size "+ abc.size)// it displays proper size
for(temp <- abc){
///it dosent come inside this loop
}
同样地,我尝试将此迭代器转换为列表/数组,但都是徒劳的。一旦我将其转换为list / arrray(toList / tiArray),结果列表/数组的大小将变为0。 无论我做什么都无法彻底迭代
我很感激你的帮助。
由于
答案 0 :(得分:1)
您可以导入JavaConversions
自动转换Iterable
。
import scala.collection.JavaConversions._
如果您仍有任何问题,可以粘贴代码吗?
values
中收到的reduce
棘手的事情是它只能遍历一次。 abc.size
会遍历values
。之后,values
无效。
所以正确的代码应该是
// don't use values
for(value <- values) {
// do something
val v = value.toString
// Don't save value, it will be reused. The content of value will be changed but the reference is same.
}
// don't use values
就像我在评论中提到的那样,value
的类型是Text
。当您遍历values
时,value
的内容将会更改,但引用相同。因此,请勿尝试将value
保存在Collection
中,否则您将获得所有项目相同的Collection
。