Ответ 1
Потоки Java 8 являются менее полнофункциональными кузенами итераторов Scala, сохраняя их способность вычислять параллельно.
Если вам не нужны параллельные вычисления (и в большинстве случаев накладные расходы не стоят - только для больших дорогостоящих заданий, вы этого хотите), то вы можете получить такую же обработку с помощью .iterator
в Scala (а затем to[Vector]
или все, что вы хотите в конце).
Java 8 потоков специализированы вручную (Scala Iterator
is not), поэтому существуют случаи, когда они быстрее, но это не из-за постоянного фактора из-за воссоздания коллекций по пути - по крайней мере, а не если вы выбрали .iterator
. (Без .iterator
, коллекции Scala оцениваются по умолчанию, коллекции Java не имеют этой опции.)
эквивалент Scala для кода Java 8, который вы написали, следующий:
val xsi = Array(1, 3, 5, 6, 7, 10).iterator
xsi.map(x => x*x).filter(_ > 15).foreach(println)
Нет никакой разницы в количестве созданных здесь коллекций с Scala vs. Java.
Вероятно, было бы неплохо принять очень понятный язык терминальной операции для документации Scala Iterator. Документы с потоком Java 8 отлично смотрятся в том, что они делают это изящно понятным, когда вы создаете описание работы и когда вы в конце концов это делаете.
Scala также предоставляет класс Stream
, который запоминает старую работу (поэтому вам не нужно ее вычислять во второй раз, если вы повторно ее используете) и различные views
, поэтому вам не нужно воссоздайте цепочку обработки каждый раз, когда вы хотите ее использовать. Например, с помощью квадрата можно
val xsv = Array(1, 3, 5, 6, 7, 10).view
val xsq = xsv.map(x => x*x)
xsq.filter(_ > 15).foreach(println)
xsq.filter(_ < 5).foreach(println)
тогда как с потоками Java 8 xsq
будет исчерпан после первой операции терминала.
Итак, Scala действительно делает все (за исключением parallelism), что делает потоки Java 8, и совсем немного больше, и надолго.
Scala также имеет параллельные коллекции, но реализация Java 8 достаточно высока по производительности, и в этот момент я бы рекомендовал использовать их в первую очередь. И снова, если ручная специализация - это ваша вещь, потоки Java 8 имеют ее для Int, Double и Long, и это большой выигрыш в производительности. (Примечание: ваш пример, используя asList
, не специализируется вручную.)
Но если вы просто хотите поставить в очередь операции и не иметь накладных расходов на создание промежуточных коллекций, это делает Scala. Вы просто должны спросить.