Scala中如何生成符合原生语义的真正Iterator[Long]
Scala 中创建符合语义的
Iterator[Long]方法 查阅相关讨论时,有开发者提到需要创建Iterator[Long]的场景,这里直接给出可落地的结论和方案:
- 首先确认:Scala SDK 确实没有提供专门直接生成原生
Iterator[Long]的专用构造器,Iterator伴生对象的通用构造方法默认返回的是泛型迭代器,会涉及Long的装箱操作。 - 关于「通过其他集合调用
.iterator获取Iterator[Long]」的方式,是否符合Iterator语义,核心看你用的集合本身是不是惰性的:- 如果你先构造了
List[Long]、Array[Long]这类严格集合,再调用.iterator,所有元素在迭代开始前就已经全部生成并存储在内存里,完全丢失了Iterator惰性生成、遍历后不保留元素的核心特性,本质是把已经存好的集合元素逐个吐出来,不是真正意义上的惰性迭代器。 - 如果你用的是
View、LazyList这类本身惰性的集合,调用.iterator时可以保留惰性,但要注意不要在调用.iterator前触发任何强制求值操作,否则还是会提前缓存元素。
- 如果你先构造了
- 要拿到完全符合语义、常量内存占用、无装箱的
Iterator[Long],最稳妥的方案是直接基于状态自定义迭代器,不需要依赖任何中间集合,举个最基础的连续Long序列迭代器实现:
import scala.collection.AbstractIterator // 生成从start位置开始、步长为1的Long迭代器 def fromLong(start: Long): Iterator[Long] = new AbstractIterator[Long] { private var cur = start override def hasNext: Boolean = cur < Long.MaxValue override def next(): Long = { val res = cur cur += 1 res } }
这个实现全程只存一个当前值的状态,每返回一个元素就更新状态,之前遍历过的元素没有任何引用保留,会被GC直接回收,完全满足「惰性、遗忘式」的语义要求。如果你需要生成自定义规则的Long序列,只需要修改next()里的状态更新逻辑即可。
- Scala 2.13+ 版本也可以用内置的
unfold方法快速生成,不需要自己写继承类,效果完全一致:
val longIter = Iterator.unfold(0L) { cur => Option.when(cur < Long.MaxValue)((cur, cur + 1)) }
避坑提示:不要为了方便先构造大尺寸的严格集合再取迭代器,这种方式在序列长度很大时会直接占用大量堆内存,完全丢失Iterator的内存优势。
内容的提问来源于stack exchange,提问作者Darren Bishop
相关产品推荐
相关产品推荐

