2009-07-10 210 views
54

我正在实现一个接口,其功能类似于可以包含对象类型的表。接口规定了以下功能:如何将Double []转换为double []?

double[] getDoubles(int columnIndex); 

在那里我难倒的是,在我的实现,我存储在二维Object阵列(Object[][] data)表中的数据。当我需要返回值,我想要做以下(假设getDoubles()将只包含双打一列被调用,所以不会有ClassCastExceptions):

double[] getDoubles(int columnIndex) { 
    return (double[]) data[columnIndex]; 
} 

但是 - Java的没有按不允许Object[]转换为double[]。将它转换为Double[]是可以的,因为Double是一个对象而不是原语,但是我的接口指定数据将作为double[]返回。

所以我有两个问题:

  1. 有什么办法,我可以得到列的数据出来Object[][]表,并返回原语数组?
  2. 如果我更改界面以返回Double[],是否会有任何性能影响?
+0

为什么你需要将数据作为Object [] []? – notnoop 2009-07-10 14:50:50

+0

该表可以存储任何类型的数据:字符串,双精度,整数,其他类型等。 – Brian 2009-07-10 14:52:08

+0

然后,如何确保columnIndex中的数组仅包含双精度/双精度? – notnoop 2009-07-10 15:00:00

回答

31

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

就性能而言,在Java中装箱和拆箱基元有一段时间。如果该设置足够小,则不会看到任何性能问题。

+4

虽然不是直接适用的,但C#中用原始类型与盒装类型对大型(一百万个元素)数组进行排序的测试显示,原始排序的速度快3倍。我提到这一点是因为它说明了自动装箱/拆箱成本可能很大。 – cletus 2009-07-10 16:36:51

3

如果你想返回一个double[],你需要创建一个new double[],填充它并返回它。

这可能是一个很好的建筑决策。首先,将Object[]转换为Double[]并没有多大意义;它不是一个真正的数组Double,因为它也可能有Object。其次,如果直接返回数组,用户代码可以修改它并更改对象的内部结构。

主要的性能影响将返回double[]的数组,由于拆箱和分配成本。

7

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

SO:

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

请纠正我,如果我死错在这里。

76

如果您不介意使用第三方库,commons-lang拥有ArrayUtils类型以及多种操作方法。

Double[] doubles; 
... 
double[] d = ArrayUtils.toPrimitive(doubles); 

也有互补的方法

doubles = ArrayUtils.toObject(d); 

编辑:要回答这个问题的其余部分。这样做会有一些开销,但除非阵列真的很大,否则不应该担心。在重构之前先测试它是否是一个问题。

实现你实际询问的方法会给出类似的结果。

double[] getDoubles(int columnIndex) { 
    return ArrayUtils.toPrimitive(data[columnIndex]); 
} 
0

我将第二所述ArrayUtils回答,并添加了1.5 autoboxing documentationvia)有点表明没有内建的方法:

存在从数组类型SC没有允许转换[]数组键入TC []如果没有允许比SC字符串转换其他 转换至TC

1

我没有什么可以补充超出jjnguy和Eric k是真正的问题奥斯洛说。

但只是一个方面说明:你提到将一个Object数组转换为Double数组。以下将不起作用:

Object[] oa=new Object[3]; 
oa[0]=new Double("1.0"); 
oa[1]=new Double("2.0"); 
oa[2]=new Double("3.0"); 
Double[] da=(Double[])oa; 

最后一行将抛出类转换异常。即使数组中的每个元素确实是Double,该数组也被创建为对象数组,而不是Doubles数组,因此该变体无效。

32

在Java 8,这是一个班轮:

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

注意,原来阵列上这仍然迭代并创建一个新的。

1

可以利用ArrayUtils转换

Double[] d; // initialise 
double[] array = ArrayUtils.toPrimitive(d); 

无需循环的整个数据。