如何将Double []转换为double []?

Bri*_*ian 63 java arrays autoboxing

我正在实现一个接口,其功能类似于可以包含对象类型的表.接口指定以下功能:

double[] getDoubles(int columnIndex);
Run Code Online (Sandbox Code Playgroud)

我感到难过的是,在我的实现中,我将表数据存储在2D Object数组(Object[][] data)中.当我需要返回值时,我想要执行以下操作(假设getDoubles()只会在包含双精度的列上调用,因此将不会ClassCastExceptions):

double[] getDoubles(int columnIndex) {
    return (double[]) data[columnIndex];
}
Run Code Online (Sandbox Code Playgroud)

但是 - Java不允许Object[]强制转换为double[].将它转换Double[]为正常是因为它Double是一个对象而不是一个原语,但我的接口指定数据将作为一个返回double[].

所以我有两个问题:

  1. 有什么办法可以从Object[][]表中获取列数据并返回原语数组吗?
  2. 如果我确实将界面更改为返回Double[],是否会对性能产生影响?

Ric*_*ler 86

如果您不介意使用第三方库,则commons-lang具有ArrayUtils类型以及各种操作方法.

Double[] doubles;
...
double[] d = ArrayUtils.toPrimitive(doubles);
Run Code Online (Sandbox Code Playgroud)

还有补充方法

doubles = ArrayUtils.toObject(d);
Run Code Online (Sandbox Code Playgroud)

编辑:回答问题的其余部分.这样做会有一些开销,但除非阵列非常大,否则你不必担心它.首先测试它,看看在重构之前它是否是一个问题.

实现你实际问过的方法会得到类似的东西.

double[] getDoubles(int columnIndex) {
    return ArrayUtils.toPrimitive(data[columnIndex]);
}
Run Code Online (Sandbox Code Playgroud)

  • 使用第三方库可能看起来不错(毕竟,单行代码看起来比丑陋的for循环好得多......)但实现与手动双向转换没有什么不同.最差!每次迭代甚至都有一个三元运算符可能导致更多的计算机处理.我的观点是,"更喜欢"解决方案应该考虑性能和有用性而不是代码美学.:)我的2c. (5认同)

Inf*_*igo 48

在Java 8中,这是一个单行:

Double[] boxed = new Double[] { 1.0, 2.0, 3.0 };
double[] unboxed = Stream.of(boxed).mapToDouble(Double::doubleValue).toArray();
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然会遍历原始数组并创建一个新数组.


jjn*_*guy 33

不幸的是,Double如果要将其转换为a,则需要遍历整个列表并取消装箱double[].

就性能而言,Java中的装箱和拆箱原语有一些时间.如果该集合足够小,您将看不到任何性能问题.

  • 虽然不能直接应用,但在C#中对基本与盒装类型的大(一百万个元素)数组进行排序的测试表明原始排序的速度是原来的3倍.我之所以提到这一点是因为它说明了自动装箱/拆箱费用可能很重要. (4认同)

Eri*_*low 7

你可以使用a for each循环来构造一个相同大小的临时数组,然后将每个单独的元素转换为double,但是在数组中.

所以:

double[] tempArray = new double[data[columnIndex].length];
int i = 0;
for(Double d : (Double) data[columnIndex]) {
  tempArray[i] = (double) d;
  i++;
}
Run Code Online (Sandbox Code Playgroud)

如果我在这里错了,请纠正我.