Понимание работы Java Stream.limit () - PullRequest
0 голосов
/ 25 октября 2018

Я учился Stream.limit() говорит:

Возвращает поток, состоящий из элементов этого потока, усеченный до длины не более maxSize.

Это можно понять из:

Stream.of(1,2,3,4,5,6,7,8)
    .limit(3)
    .forEach(i -> {
        System.out.print(i + ",");
    });  //prints: 1,2,3,

Однако при использовании с другими потоковыми методами он имеет эффект обработки элементов в пакете:

Stream.of(1,2,3,4,5,6,7)
    .filter(i -> {
        System.out.println("Filtering "  + i + ": " + (i%2 == 0));
        return i%2 == 0;
    })
    .map(i-> {
        System.out.println("Mapping " + i + " to " + i*i);
        return i*i;
    })
    .limit(2)
    .forEach(i -> System.out.println("---> " + i));

Печать:

Filtering 1: false
Filtering 2: true
Mapping 2 to 4
---> 4
Filtering 3: false
Filtering 4: true
Mapping 4 to 16
---> 16

Здесь вы можете видеть, что элементы обрабатываются в пакете из 2.

У меня следующие сомнения:

  1. Почему он не обработантолько первые два элемента 1 и 2?То есть, почему вывод не просто:

     Filtering 1: false
     Filtering 2: true
     Mapping 2 to 4
     ---> 4
    
  2. Почему он не обработал последние четыре элемента 5,6,7 и 8 и напечатал следующее?:

     Filtering 5: false
     Filtering 6: true
     Mapping 6 to 36
     ---> 36
     Filtering 7: false
     Filtering 8: true
     Mapping 8 to 64
     ---> 64
    

1 Ответ

0 голосов
/ 25 октября 2018
  1. Обе 1 и 2 были обработаны.1 нечетно, поэтому filter удаляет его из потокового конвейера.2 является четным и прошел весь конвейер потока, в результате чего 4 распечатывается в forEach.

  2. Потоки ленивы по своей природе.Поскольку вы использовали limit(2), только два элемента пройдут через шаг конвейера limit.2 и 4 прошли через весь потоковый конвейер, в результате чего 4 и 16 были распечатаны в forEach.

limit() - это короткое замыкание с состояниемпромежуточная операция, согласно документам :

Операции короткого замыкания, такие как limit (n) или findFirst (), могут позволить вычислениям на бесконечных потоках завершиться за конечное время.

...

Кроме того, некоторые операции считаются операциями с коротким замыканием.Промежуточная операция - это короткое замыкание, если при наличии бесконечного ввода она может привести к конечному потоку в результате.Работа терминала является коротким замыканием, если при наличии бесконечного входа она может завершиться за конечное время.Наличие операции короткого замыкания в конвейере является необходимым, но не достаточным условием для нормальной обработки бесконечного потока в конечном времени.

...