我只是想探索REPL中String
对象和List[Int]
对象的迭代器的行为,测试如下所示:
scala> val list = List(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
scala> val itL = list.iterator
itL: Iterator[Int] = non-empty iterator
scala> List(8,5,list.size-13).map(itL.take(_).mkString)
res85: List[String] = List(12345678, 910111213, 141516)
scala> val st = "abcdefghijklmnop"
st: String = abcdefghijklmnop
scala> val itS = st.iterator
itS: Iterator[Char] = non-empty iterator
scala> List(8,5,st.size-13).map(itS.take(_).mkString)
res84: List[String] = List(abcdefgh, abcde, abc)
为什么迭代器的行为有所不同?在String
对象的情况下,我的预期输出是:
List[String] = List(abcdefgh, ijklm, nop)
如果可能的话,有人可以通过示例进行解释。
另一个观察结果是:Range
对象的迭代器的行为也与String
对象完全相似
如下所示:
scala> val x = (1 to 16)
x: scala.collection.immutable.Range.Inclusive = Range 1 to 16
scala> val t = (1 to 16).iterator
t: Iterator[Int] = non-empty iterator
scala> List(8,5,x.size-13).map(t.take(_).mkString)
res103: List[String] = List(12345678, 12345, 123)
如果将Range
转换为List
或Set
,则各个迭代器的行为将完全按照我的期望:
scala> val x1 = (1 to 16).toList
x1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
scala> val t1 = x1.iterator
t1: Iterator[Int] = non-empty iterator
scala> List(8,5,x1.size-13).map(t1.take(_).mkString)
res104: List[String] = List(12345678, 910111213, 141516)
scala> val x2 = (1 to 16).toSet
x2: scala.collection.immutable.Set[Int] = Set(5, 10, 14, 1, 6, 9, 13, 2, 12, 7, 3, 16, 11, 8, 4, 15)
scala> val t2 = x2.iterator
t2: Iterator[Int] = non-empty iterator
scala> List(8,5,x2.size-13).map(t2.take(_).mkString)
res105: List[String] = List(51014169132, 12731611, 8415)
答案 0 :(得分:8)
Iterator.take(n:Int)
API documentation上有一个注释:
重用:调用此方法后,应丢弃被调用的迭代器,而仅使用返回的迭代器。使用旧的迭代器是不确定的,可能会发生更改,并且可能还会导致新的迭代器发生更改。
您似乎发现了一些“未定义”的行为。