Stateless stream gatherers, which process each element of the stream independently, don’t need an initializer function. That’s because the role of
the initializer function is to set up the gatherer’s private state object.
The gatherer interface provides factory methods that create gatherers without taking an initializer as an argument:
-
ofSequential(Gatherer.Integrator<Void,T,R> integrator)
-
ofSequential(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super R>>
finisher)
Using these specific factory methods to create stateless gatherers is preferable because it clearly communicates their stateless nature.
This rule reports the use of ofSequential(Gatherer.Integrator<Void,T,R> integrator, BiConsumer<Void, Gatherer.Downstream<? super
R>> finisher)
when it returns a stateless gatherer.
Code examples
Noncompliant code example
private static Gatherer inRange(int start, int end) {
return Gatherer.<Integer, Void, Integer>ofSequential(
() -> null, // Noncompliant: unnecessary initializer
(_, element, downstream) -> {
if (element >= start && element <= end)
return downstream.push(element - start);
return !downstream.isRejecting();
},
(_, downstream) -> downstream.push(-1)
);
}
Compliant solution
private static Gatherer inRange(int start, int end) {
return Gatherer.<Integer, Integer>ofSequential(
(_, element, downstream) -> {
if (element >= start && element <= end)
return downstream.push(element - start);
return !downstream.isRejecting();
},
(_, downstream) -> downstream.push(-1)
);
}