Глядя на этот вопрос: Как динамически выполнять фильтрацию в 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().
Если я удалю эту строку, последствиями будет то, что счетчик будет равен НУЛЮ, когда я попытаюсь выполнить limit. Я каким-то образом обманываю требование «эффективно окончательного», используя изменяемый объект.
Я могу ошибаться, но я понимаю, что поток создается первым, поэтому, если мы использовали изменяемые объекты для передачи параметров любому из шагов в потоке, они будут приняты при создании потока.
У меня вопрос, если мое предположение верно, то зачем это нужно? Поток (если он непараллельный) может проходить последовательно через все этапы (фильтр, сопоставление и т. д.), поэтому это ограничение не требуется.