Reputation: 61
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
?
Upvotes: 5
Views: 1723
Reputation: 4959
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]));
Upvotes: 6
Reputation: 140318
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.
Upvotes: 6