Недавно я узнал о Stream
с в Java 8 и увидел этот пример:Понимание Java 8 записи потока
IntStream stream = IntStream.range(1, 20);
Теперь, давайте скажем, что мы хотим, чтобы найти первое число, которое divisable как на 3 и 5 . Мы, вероятно, filter
дважды и findFirst
следующим образом:
OptionalInt result = stream.filter(x -> x % 3 == 0)
.filter(x -> x % 5 == 0)
.findFirst();
Это все звучит довольно разумно. Удивительное, когда я пытался сделать это:
OptionalInt result = stream.filter(x -> {System.out.println(x); return x % 3 == 0;})
.filter(x -> {System.out.println(x); return x % 5 == 0;})
.findFirst();
System.out.println(result.getAsInt());
я ожидал получить что-то вроде: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
, а затем: 3 6 9 12 15 18
. Потому что мы первые итерации по всем номерам от 1 до 20, отфильтровать только те, которые divisable на 3, а затем перебирать этот новый Stream
и найти те, которые divisable на 5.
Но вместо этого я получил этот результат: 1 2 3 3 4 5 6 6 7 8 9 9 10 11 12 12 13 14 15 15 15
Похоже, что это не соответствует всем номерам. Более того, похоже, что он проверяет x % 5 == 0
только на те числа, которые делятся на 3.
Я не понимаю, почему он не перебирает все числа.
Вот онлайн фрагмент кода: http://www.tryjava8.com/app/snippets/5454a7f2e4b070922a64002b