我正在使用一个API,该API结果返回二维float
数组。我想使用流API中的flatMap
方法处理此数据,但需要将double
数组传递到其方法中。我试图通过将float[][]
强制转换为double[][]
来解决此问题,但是即使使用float[]
也无法解决。这是一个JShell会话转储:
-> 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;
因此,我的问题是:当从float[]
投射到double[]
是合法的时候,为什么我们不能将float
投射到double
?
答案 0 :(得分:5)
如果要查看float[]
占据的存储空间,就好像它是double[]
,那么数组中的偏移量将是全部错误的。因此,当您查看双重#1时,您会看到#1浮点数和#2浮点数的一部分。这就是为什么您需要转换,而不仅仅是转换。
换句话说,Java语言规范根本不提供与转换相关的语法形式的转换。
回到原来的问题,这里是Brian Goetz的一个很好的技巧:
DoubleStream ds = IntStream.range(0, floatArray.length)
.mapToDouble(i -> floatArray[i]);
最后,通过上述技巧,这是您的flatMap DoubleStream:
DoubleStream ds = Arrays.stream(float2dArray)
.flatMapToDouble(floatArray -> IntStream.range(0, floatArray.length)
.mapToDouble(i -> floatArray[i]));
答案 1 :(得分:5)
数组是引用类型,甚至是具有基本元素的数组。
强制引用类型实际上对基础对象没有任何作用:它只是告诉编译器“相信我,我比你知道更多类型信息:对Foo的引用可以安全地处理作为对酒吧的参考”。
除非编译器可以证明强制类型转换不安全,否则它会信任您并允许您执行;由程序员(程序员)来检查它是否安全,或者在运行时面临ClassCastExceptions。
因此,将float[]
强制转换为double[]
不会更改基础对象,它只会更改编译器允许您对其进行的操作。
但是一旦您可以将其视为double[]
,就可以要求JVM将double
分配给该数组的元素。 double
不适合float
,因此有两种选择:
float[]
分配给double[]
,以阻止您陷入困境。第二个选择更简单,那就是他们做出的选择。
请注意,您可以通过float[]
进行投射,从而将double[]
投射到Object
:
float[] f = ...
double[] d = (double[]) (Object) f;
这将在运行时失败,除非f
为空。