I'm using an API that returns two-dimensional float
array as a result. I'd like to process this data using the flatMap
method from the streaming API, but I need to pass arrays of double
s into its methods. I've tried to work it around by casting float[][]
into double[][]
, but it didn't work, even with float[]
. Here's a JShell session dump:
-> new float[] {1.02f, 4.32f, 65.4f}
Expression value is: [F@2b98378d
assigned to temporary variable $1 of type float[]
-> double[] arrayOfDoubles = (double[]) $1
Error:
incompatible types: float[] cannot be converted to double[]
double[] arrayOfDoubles = (double[]) $1;
So, my question is: why can't we cast float[]
into double[]
, when it's fairly legal to cast from float
to double
?
The doubleValue() method of Java Float class returns a double value corresponding to this Float Object by widening the primitive values or in simple words by directly converting it to double via doubleValue() method .
floatValue() to Convert Double to Float in Java. Another way to convert a double value into a float data type in Java is by using the wrapper class Double. This class wraps a primitive data type double in an object.
Doubles are more precise and the extra storage cost is almost always negligible. So in Java by default 2.1 is a double type. Now to convert double to float you need to cast while assigning double data to double type cast is not required.
Arrays are reference types, even arrays with primitive elements.
Casting reference types doesn't actually do anything to the underlying object: it merely tells the compiler "trust me, I know more type information than you: this reference to a Foo can be safely treated as a reference to a Bar".
Unless the compiler can prove that the cast is unsafe, it trusts you and lets you do it; it is on you, the programmer, to check that it is safe, or face ClassCastExceptions at runtime.
So, casting a float[]
to a double[]
doesn't change the underlying object, it merely changes what the compiler lets you do with it.
But once you can treat it like a double[]
, you can ask the JVM to assign a double
to an element of that array. double
doesn't fit in float
, so there are two choices:
float[]
to a double[]
.The second choice is simpler, and that is the choice they made.
Note that you can cast a float[]
to a double[]
, by casting via Object
:
float[] f = ...
double[] d = (double[]) (Object) f;
This will fail at runtime, however, unless f
is null.
If you were to look at the memory space inhabited by a float[]
as if it were double[]
, then the offsets into the array would be all wrong. So you would be seeing part of float #1 and float #2 when you look at double #1. That's why you need conversion, not just casting.
Put another way, the Java Language Specification simply doesn't supply such a conversion in the form of casting related syntax.
Getting back to your original problem, here is an excellent tip from Brian Goetz:
DoubleStream ds = IntStream.range(0, floatArray.length)
.mapToDouble(i -> floatArray[i]);
And finally, here is your flatMap DoubleStream, via the above trick:
DoubleStream ds = Arrays.stream(float2dArray)
.flatMapToDouble(floatArray -> IntStream.range(0, floatArray.length)
.mapToDouble(i -> floatArray[i]));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With