Разглеждайки този въпрос: Как да извършвам динамично филтриране в Java 8?
Проблемът е да се съкрати поток след изпълнение на филтър. Не мога да използвам лимит, защото не знам колко дълъг е списъкът след филтъра. И така, можем ли да преброим слементите след филтъра?
Така че реших, че мога да създам клас, който се брои и да прекара потока през карта. 8/22856514#22856514">Кодът е в този отговор.
Създадох клас, който се брои, но оставя елементите непроменени, използвам функция тук, за да избегна използването на ламбда, които използвах в другия отговор:
class DoNothingButCount<T > implements Function<T, T> {
AtomicInteger i;
public DoNothingButCount() {
i = new AtomicInteger(0);
}
public T apply(T p) {
i.incrementAndGet();
return p;
}
}
Така че моят поток най-накрая беше:
persons.stream()
.filter(u -> u.size > 12)
.filter(u -> u.weitght > 12)
.map(counter)
.sorted((p1, p2) -> p1.age - p2.age)
.collect(Collectors.toList())
.stream()
.limit((int) (counter.i.intValue() * 0.5))
.sorted((p1, p2) -> p2.length - p1.length)
.limit((int) (counter.i.intValue() * 0.5 * 0.2)).forEach((p) -> System.out.println(p));
Но въпросът ми е за друга част от моя пример.
collect(Collectors.toList()).stream().
Ако премахна този ред, последствията са, че броячът е НУЛА, когато се опитам да изпълня лимит. Някак си мамя изискването "ефективно окончателно", като използвам променлив обект.
Може да греша, но разбирам, че първо се изгражда потокът, така че ако сме използвали променливи обекти, за да предадем параметри на която и да е от стъпките в потока, те ще бъдат взети, когато потокът бъде създаден.
Въпросът ми е, ако предположението ми е правилно, защо е необходимо това? Потокът (ако не е паралелен) може да бъде преминат последователно през всички стъпки (филтър, карта...), така че това ограничение не е необходимо.