我有一个定义如下的函数(为了参数而简化):
def sendRecords(records: Iterator[Map[String, String]]) = {
records.sliding(10,10).foreach { case recordList => println(recordList) }
}
当我调用此函数时,我可以从println(以及知道预期的答案是什么)看到recordList确实是一批10,但不知何故来自'记录的某些项目&# 39;似乎被跳过了。在这种情况下,输出缺少第1,第12,第13,第24,第25 ......(即似乎有一些奇怪的正常性)。请注意,每个元素都是string->的映射。字符串(内容是保密的),但为了说明起见,输出的简化形式可以是
[1,2,3,4,5,6,7,8,9,10],[13,14,15,16,17,18,19,20,21,22],[....]
用于批处理案例和
[0,1,2,3,4,5,6,7,8,9], [10,11,12,13,14,15,16,17,18,19],[....]
用" toList.iterator" (见下文),这是预期的。在这些输出中,我已经用标识它们的索引替换了地图。
我完全不知道为什么会发生这种情况。请注意'记录'是我自己实现的迭代器(即hasNext和next) - 我怀疑它很重要。但实施起来相当复杂。我已添加了底部的主要部分。
有些迹象表明它是正确的
records.toList.iterator.sliding(10,10).foreach { case recordList => println(recordList) }
工作正常,
records.foreach { println }
也看起来像预期的那样(即它单独打印每个元素,列表完成)。
有人知道这里有什么 - 或者建议我可以尝试其他一些事情吗?任何帮助将非常感激。我正在使用scala 2.10.5。
(请注意,虽然toList.iterator hack有效,但这里不能接受,因为它会在内存中构建整个列表,这在生产中会太大了。)
谢谢! -Joris。
迭代器尚未完全整理,所以请原谅一些潜在的狡猾的代码(这可能导致了这个问题),但它的想法是迭代逗号分隔的文件(即"行"输入)具有相当复杂的标头定义(因此是状态方法)。我无法显示解码器,因为这是保密的,但我希望这应该足够了。也许我的hasNext / next存在缺陷。
class DecodingIterator(lines: Iterator[String]) extends Iterator[Map[String, String]] {
val decoder = new StatefulDecoder()
var cachedRecord = Map[String,String]()
def hasNext: Boolean = {
if (!lines.hasNext || decoder.inState(decoder.Finished()))
false
else {
while(!decoder.inState(decoder.Data())) {
decoder.processLine(lines.next)
}
decoder.processLine(lines.next)
cachedRecord = decoder.lastRecord
!decoder.inState(decoder.Finished())
}
}
def next = cachedRecord
}
答案 0 :(得分:0)
正如对问题的评论中所讨论的那样,问题在于迭代器的实现,迭代器在“hasNext'”上的表现并不明显。 (并且'滑动'导致连续多次调用它。)
修好后,一切正常。 感谢大家的帮助。