could somebody take a look at the sentence from OCP Java SE 11 Programmer II Study Guide, p. 221 and tell me, whether I'm wrong, when I'm saying that this is an errata, please?
„If the stream were empty, we'd have a count and sum of zero. The other methods would return an empty optional.“
I don't understand this sentence, because we are talking about summarizing statistics, e.g. IntSummaryStatistics, and their methods, which always return primitive. This sentence would be correct, if it would be in the context of primitive streams.
When I have a primitive stream (IntStream) and it's empty, for example average() method returns OptionalDouble. However, in the context of IntSummaryStatistics, the getAverage() method returns always double.
Please explain more; I can't at the moment see what the problem is: sorry.
posted 3 weeks ago
Campbell Ritchie wrote:Please explain more; I can't at the moment see what the problem is: sorry.
Well, let me cite the book, p. 220/221:
You've learned enough to be able to get the maximum value from a stream of int primitives. If the stream is empty, we want to throw an exception.
This should be old hat by now. We got an OptionalInt because we have an IntStream. If the optional contains a value, we return it. Otherwise, we throw a new RuntimeException.
Now we want to change the method to take an IntStream and return a range. The range is the minimum value subtracted from the maximum value. Uh-oh. Both min() and max() are terminal operations, which means that they use up the stream when they are run. We can't run two terminal operations against the same stream. Luckily, this is a common problem and the primitive streams solve it for us with summary statistics. Statistic is just a big word for a number that was calculated from data.
Here we asked Java to perform many calculations about the stream. Summary statistics include the following:
• Smallest number (minimum): getMin()
• Largest number (maximum): getMax()
• Average: getAverage()
• Sum: getSum()
• Number of values: getCount()
If the stream were empty, we'd have a count and sum of zero. The other methods would return an empty optional.
I'm questioning that last sentence, because it looks like getMin(), getMax() and getAverage() methods of IntSummaryStatistics would return empty optional. But that's not the case. Here are definitions of IntSummaryStatistics methods:
As you can see, all methods of IntSummaryStatics (same as DoubleSummaryStatistics or LongSummaryStatistics) return primitives. The last sentence would be valid, if we were talking about IntStream (DoubleStream, LongStream) methods (see method definitions below ↓), which return Optionals for methods min(), max() and average().
It's possible, that I'm not reading this correctly, but the last sentence is for me in the context of summary statistics objects, so even when IntSummaryStatistics is obtained from an empty stream, its methods should return primitives instead of their wrappers.
posted 3 weeks ago
Daniel Polách wrote:. . . I'm questioning that last sentence . . .
Thank you for the additional details, which make the question so much clearer. I now think you are correct.
I tried running IntStream.of().summaryStatistics() on JShell and didn't see any Optionals.
Let's look at the Java11 documentation for summaryStatistics(). It says it returns a summary statistics object, so let's look at its methods. As you said, the getXXX() methods return int except for average which returns double.
It is correct about IntStream#max() returning an OptionalInt.
It had never occurred to me that you can calculate the range like that, but it is pretty obvious when you think about it. There are some corner cases: the range of a 1‑element Stream is 0, which sounds correct. But the range of a 0‑element Stream is ??, and Streams with large ranges (both positive and negative elements) may have a negative result from that subtraction because of overflow errors.
I shall let you find out the range of a 0‑element Stream yourself. I shall also let you suggest ways of getting the range without overflow.
I looked up some of those methods in Java8 (one example) and didn't notice any differences.
I would have said that one possible response to an empty optional is to throw an exception; maybe calling orElse(0) would be a viable alternative.