Подтвердить что ты не робот

Почему Stream.limit не работает в этом фрагменте?

List<Integer> integer = Stream.generate(new Supplier<Integer>() {
    int i = 0 ;

    @Override
    public Integer get() {
        return ++i;
    }
}).filter(j -> j < 5)
  .limit(10)   // Note the call to limit here
  .collect(Collectors.toList());

В ответ на мое ожидание вызов collect никогда не возвращается. Установка limit до filter дает ожидаемый результат. Зачем?

4b9b3361

Ответ 1

Так как есть только 4 элемента, которые пропускают фильтр, limit(10) никогда не достигает 10 элементов, поэтому конвейер Stream продолжает генерировать новые элементы и подавать их в фильтр, пытаясь достичь 10 элементов, которые проходят фильтр, но так как только первые 4 элемента пропускают фильтр, обработка никогда не заканчивается (по крайней мере до переполнения i).

Конвейер Stream недостаточно умен, чтобы знать, что больше не может проходить фильтр, поэтому он продолжает обрабатывать новые элементы.

Ответ 2

Отбрасывание предложений limit и filter имеет разные типы поведения.

Если вы сначала поместите limit, поток сначала сгенерирует 10 целых чисел [1..10], а затем отфильтрует их, оставив только те, которые меньше 5.

В исходном порядке, при первом применении filter, целые числа генерируются и фильтруются до тех пор, пока вы не достигнете 10 элементов. Это не бесконечный оператор, так как i в поставщике будет в конечном итоге переполняться, но для достижения MAX_INT потребуется некоторое время, особенно на медленном компьютере.

Ответ 3

Если вы хотите остановить либо, если число 5 достигнуто, либо собрано 10 элементов, в Java-9 добавлен метод Stream.takeWhile():

List<Integer> integer = Stream.generate(new Supplier<Integer>() {
    int i = 0 ;

    @Override
    public Integer get() {
        return ++i;
    }
}).takeWhile(j -> j < 5).limit(10).collect(Collectors.toList());

Ответ 4

Он завершится после того, как Поставщик переполнит и начнет генерировать отрицательные числа. Полученный список будет содержать:

[1, 2, 3, 4, -2147483648, -2147483647, -2147483646, -2147483645, -2147483644, -2147483643]

Причина этого в других ответах. На моей машине i7 потребовалось 40 секунд.