Поток в котлин

  • Как Котлин будет работать над следующим кодом?
  • Будет ли создаваться коллекция из 5000000 целых чисел как временная коллекция или будет ли фильтр сразу же forEach результат в значение forEach что означает, что будут рассмотрены только 20 целых чисел?
  • Если нет, как мне удастся избежать промежуточной коллекции?

Код:

 class Tests { @Test fun test() { var counter = 0 (1..10_000_000).filter { it % 2 == 1 }.forEach { counter++ if (counter > 10) return } } } 

В примере кода используются операции с Iterable<T> , которые работают с нетерпением: .filter { ... } обрабатывает весь диапазон и создает список, в котором .filter { ... } промежуточные результаты.

Чтобы изменить это, рассмотрите возможность использования Sequence<T> (например, с .asSequence() ), которая работает лениво, так что промежуточные операции, такие как .filter { ... } производят другую ленивую последовательность и выполняют только работу, когда элементы запрашиваются терминальные операции, такие как .forEach { ... } :

 (1..10000000).asSequence() .filter { it % 2 == 1 } .forEach { /* ... */ } 

См .: Итерабельность и последовательность Котлина выглядят точно так же. Почему требуются два типа?

Вы действительно можете увидеть ответ на свой вопрос довольно быстро, просто добавив println(it) в filter :

 //... .filter { println(it) it % 2 == 1 } //... 

Вы увидите каждое напечатанное число. Это потому, что ваша обработка работает с нетерпением, как объяснено здесь .

Как уже было (1..10_000_000).asSequence() , ленивые последовательности для спасения: (1..10_000_000).asSequence()

Теперь, println(it) в filter будет печатать только числа 1..21 , что определенно предпочтительнее в вашем примере.

Intereting Posts