Почему поток не ограничен, есть ли фильтр () до limit ()? [Дубликат]

Существует алгоритм пакетной карты: вы создаете упорядоченный массив чисел («пакет карт»), и на каждой итерации вы выбираете номер в произвольной позиции (удалив выбранный номер из «карточной партии», конечно) .

34
задан Bakuriu 10 December 2015 в 09:01
поделиться

4 ответа

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

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

33
ответ дан Eran 16 August 2018 в 04:55
поделиться

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

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

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

25
ответ дан Mureinik 16 August 2018 в 04:55
поделиться
  • 1
    Я не рассматривал возможное переполнение int. +1 – Eran 9 December 2015 в 08:34
  • 2
    Возможно, речь идет о том, когда оптимизатор начинает свою работу, но на моей машине переполнение и последующее завершение операции происходит менее чем за секунду ... – Holger 9 December 2015 в 10:27

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

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

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

9
ответ дан Oliv 16 August 2018 в 04:55
поделиться

Если вы хотите остановить либо , если число 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());
17
ответ дан Tagir Valeev 16 August 2018 в 04:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: