The standard Java libraries provide nice Collector utils for reduction, such as summingInt()
, summingLong()
, and summingDouble()
. It does not look like there is summingFloat()
, though. Is there a suggested workaround? Or perhaps are floats discouraged for some reason?

- 523
- 6
- 14
-
1No idea if it is a good practice or not, but you can just look at `Collectors.summing...` implementation and try to write something like that yourself. It should take 2 min. – Amongalen May 14 '20 at 14:40
-
2`Or perhaps are floats discouraged for some reason?` the general advise is to stay away from them because `doubles` offer far more accucary and the extra memory required doesn't really make a difference. – cegredev May 14 '20 at 14:47
-
though i'm not sure , but i think the reason is it's more precise to use double. – Akash Jain May 14 '20 at 14:47
2 Answers
are floats discouraged for some reason?
Yes, they are discouraged because of the very low precision they have, as low as 6 digits (they have "from 6 to 9 significant decimal digits precision", according to Wikipedia).
The extra storage needed is generally not an issue, while the lack of precision can be a huge issue, that may not present itself with small test cases, so it's safer to use double
unless absolute necessary.
If the objects you're streaming have a method returning a float
, and you want to sum the values from that method, use summingDouble(...)
and "cast" the result back to float
using the floatValue()
method of Double
.
float sum = list.stream()
.collect(Collectors.summingDouble(o -> o.getFloat()))
.floatValue();

- 154,647
- 11
- 152
- 247
-
4`summingDouble()` is preferred as it tries to improve accuracy with compensated summation. – Karol Dowbecki May 14 '20 at 15:35
Is there a suggested workaround?
You could convert the float
values to double
as follows:
Stream.of(1F, 2F, 3F).mapToDouble(Float::doubleValue).sum();
Or use reduce
to sum the float
values (mind that this will return a Optional<Float>
instead of the primitive type as the previous solution do):
Stream.of(1F, 2F, 3F).reduce(Float::sum);
Or perhaps are floats discouraged for some reason?
It looks like the reason for the existence of only 3 primitive stream types is:
To avoid a lot of unnecessary object creation and work we have three primitive stream types
This answer also shows a similar reason for this.
Baeldung adds the boxing overhead argument to the matter:
Primitive streams are limited mainly because of boxing overhead and because creating specialized streams for other primitives isn't' that useful in many cases.
EDIT
As Karol mentioned in the comments, to avoid floating point innacuracy, you may convert it to float
after using sum()
from DoubleStream
, as the first solution do:
float result = (float) Stream.of(1F, 2F, 3F).mapToDouble(Float::doubleValue).sum();
The API reference for sum()
explains how it is different from simply reducing like reduce(0, Double::sum)
:
The order of addition operations of this method is intentionally not defined to allow for implementation flexibility to improve the speed and accuracy of the computed result. In particular, this method may be implemented using compensated summation or other technique to reduce the error bound in the numerical sum compared to a simple summation of double values.

- 115
- 1
- 9
-
3reducing with `Float::sum` is not the same as compensated (Kahan) summation in Double stream `sum()` – Karol Dowbecki May 14 '20 at 15:33