В чем разница между методами итератора и представления?
scala> (1 to 10).iterator.map{_ * 2}.toList
res1: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
scala> (1 to 10).view.map{_ * 2}.force
res2: Seq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
За исключением использования next, hasNext, когда следует выбирать итератор над представлением или просматривать итератор?
Ответы
Ответ 1
Там есть огромная разница между итераторами и представлениями. Итераторы используются только один раз, вычисляют по требованию, в то время как представления используются несколько раз, каждый раз перепрограммируются, но только необходимые элементы. Например:
scala> val list = List(1,2,3).map{x => println(x); x * 2}
1
2
3
list: List[Int] = List(2, 4, 6)
scala> list(2)
res14: Int = 6
scala> list(2)
res15: Int = 6
scala> val view = List(1,2,3).view.map{x => println(x); x * 2}
view: scala.collection.SeqView[Int,Seq[_]] = SeqViewM(...)
scala> view(2)
3
res12: Int = 6
scala> view(2)
3
res13: Int = 6
scala> val iterator = List(1,2,3).iterator.map{x => println(x); x * 2}
iterator: Iterator[Int] = non-empty iterator
scala> iterator.drop(2).next
1
2
3
res16: Int = 6
scala> iterator.drop(2).next
[Iterator.next] (Iterator.scala:29)
(access lastException for the full trace)
Ответ 2
view
создает ленивый сбор/поток. Главное, что он не будет пытаться построить всю коллекцию. Это может помешать OutOfMemoryError или повысить производительность, когда вам нужны только первые несколько элементов коллекции. iterator
не дает такой гарантии.
Еще одна вещь. По крайней мере, на Range
, view
возвращает SeqView
, который является подтипом Seq
, поэтому вы можете вернуться или начать с самого начала и сделать все, что весело.
Я думаю, что разница между итератором и представлением - это вопрос впереди и позади. Ожидается, что итераторы выпустят то, что было замечено. Как только next
был вызван, предыдущий, надеюсь, отпустит. Мнения противоположны. Они обещают не получить то, что не было запрошено. Если у вас есть представление о всех простых числах, бесконечном множестве, он только приобрел эти простые числа, о которых вы просили. Это вы хотели, чтобы 100-й, 101 еще не занимался памятью.
Ответ 3
Эта страница рассказывает о том, когда использовать представления.
Таким образом, взгляды являются мощным инструментом для согласования проблем эффективность с учетом модульности. Но чтобы не быть запутанные в аспектах отсроченной оценки, вы должны ограничить взгляды к двум сценариям. Либо вы применяете представления в чисто функциональном коде где преобразования коллекции не имеют побочных эффектов. Или ты применять их по изменяемым коллекциям, где все изменения сделаны в явном виде. Лучше всего избегать сочетания взглядов и операций которые создают новые коллекции, а также имеют побочные эффекты.