Потоки ленивы.Думайте о них как о рабочих в цепи, которые передают друг другу ведра.Лень в том, что они будут просить рабочего позади них только за следующее ведро, если рабочий перед ними просит их об этом.
Так что лучше думать об этом как allMatch
- бытьпоследнее действие, таким образом жаждущее - запросить поток map
о следующем элементе, поток map
запросить поток generate
о следующем элементе и поток generate
, идущий к его поставщику, и предоставить этот элементкак только он прибудет.
Останавливается, когда allMatch
перестает запрашивать предметы.И делает это, когда знает ответ.Все элементы в этом потоке не нулевые?Как только allMatch
получает элемент, который является нулевым, он знает, что ответ false
, и завершит работу и не будет запрашивать больше элементов.Поскольку поток бесконечен, он не остановится в противном случае.
Таким образом, у вас есть два фактора, заставляющие это работать так, как он работает - один allMatch
с нетерпением запрашивает следующий элемент (до тех пор, как предыдущиене был нулевым), и поток generate
, который - для предоставления следующего элемента - возможно, должен был ждать поставщика, ожидающего, пока пользователь отправит больше ввода.
Но следует сказать,что map
не следовало использовать здесь.В map
не должно быть побочных эффектов - его следует использовать для отображения элемента одного типа на элемент другого типа.Я думаю, что этот пример использовался только в качестве учебного пособия.Гораздо проще и проще было бы использовать метод BufferedReader
lines()
, который дает вам конечное Stream
строк, поступающих из буферизованного читателя.