2 ms·
My favorite gotcha is Java's `Stream.reduce(accumulator)` doesn't call the accumulator if your stream has zero or one elements. This is used for `min(comparator
by tantalor 9d ago
My favorite gotcha is Java's `Stream.reduce(accumulator)` doesn't call the accumulator if your stream has zero or one elements. This is used for `min(comparator)` and `max(comparator)`. It's very funny when the comparator throws, but only when you have 2 or more elements.
- ndriscoll 9d agoHow is that a gotcha? If there aren't two elements how could you possibly expect a function with two arguments to be called? What would you call it with?
- tantalor 9d agoYou can easily write the code with only one-arg functions. Example: myStream.min(Comparator.comparingDouble((obj) -> { ... })); You might think: it will map over the objects and convert each object to an number, and take the object with the lowest value. Except that's not what it does. You'd be wrong!
- ndriscoll 9d agoComparator.comparingDouble returns a comparator, which is a two argument function, which is what min expects. Min can't know how your comparator is defined without reflection to do that kind of peeking, and as you point out, that kind of peeking would cause observable differences in behavior. min is a generic method. All it knows is it has a Stream<T> and a function taking two Ts. The only thing it can do is plug in Ts it gets from the stream.