将包装器数组转换为基本类型数组

5
如果我有一个原始包装类实例的数组,如何获取它们对应的基本类型数组?
Object toPrimitiveArray(Object[] wrappedArray) {
    return ?;
}

Object primitiveArray = toPrimitiveArray(new Integer[] { 1, 2, 3 });

在上面的例子中,我希望toPrimitiveArray()方法返回一个包含整数值123int[]数组。


final int[] ret = new int[wrappedArray.length]; int i=0; for (int w : wrappedArray) ret[i++] = w; return ret; - Marko Topolnik
@MarkoTopolnik,已更新问题以反映我的内容。我知道它接收一个基本包装类数组。我可以通过反射获得实际的类和关联的基本类型。 - rid
Integer.classint[]没有自动的方式。您需要为每种类型显式地执行该转换。您还需要调用不同的方法来提取基本值,以适用于每个包装器类型。您要么最终得到慢得可怜、复杂混乱的反射代码,要么得到快速、重复的字面代码。 - Marko Topolnik
针对ArrayList输入,请参考以下链接:https://dev59.com/O3RB5IYBdhLWcg3wF0LH - Ciro Santilli OurBigBook.com
4个回答

2
问题在于您的方法无法知道数组中包含的数字类型,因为您仅将其定义为对象数组,没有其他信息。因此,不可能自动产生一个原始数组而不失去编译时类型安全性。
您可以使用反射来检查对象类型:
if(obj instanceof Integer) {
    //run through array and cast to int
} else if (obj instanceof Long) {
    //run through array and cast to long
} // and so on . . .

然而,这种方式很丑陋,并且不允许编译器在代码中检查类型安全性,因此增加了出错的机会。

你能否改用Number对象的列表而不是数组?那么你就可以使用类型参数(泛型)来保证类型安全。


它可以包含任何包装器,不仅仅是数字。例如,它可以包含一个Character包装器实例的数组。在调用该方法之前,我知道肯定会传递一个包装器数组。 - rid
类型安全并不是 OP 最大的问题。 - Marko Topolnik

1

这个答案来得有些晚,但希望能对未来访问者有所帮助。我对反射解决方案的看法可以改进,但基本思路如下:

@SuppressWarnings("unchecked")
private static <TArray, TElement> TArray toArray(final Object elements, final Class<TElement> elementType)
{
  final int length = java.lang.reflect.Array.getLength(elements);
  final Object resultArray = java.lang.reflect.Array.newInstance(elementType, length);

  for (int i = 0; i < length; ++i)
  {
    final Object value = java.lang.reflect.Array.get(elements, i);

    java.lang.reflect.Array.set(resultArray, i, value);
  }

  return (TArray)resultArray;
}

然后按照以下方式使用:

final Boolean[] booleans = new Boolean[] { true, false, true, true, false };
final boolean[] primitives = toArray(booleans, boolean.class);

System.out.println(Arrays.asList(booleans));

for (boolean b : primitives)
{
  System.out.print(b);
  System.out.print(", ");
}

这会打印出以下内容:
[true, false, true, true, false]
true, false, true, true, false,

这个工具能够帮助我们从 java.sql.Array 中取出数组,因为 java.sql.Array 只提供了一个数组的 Object


1
这个怎么样?
int[] toPrimitiveArray(Integer[] wrappedArray) {
  int[] array = new int[wrappedArray.length];
  for(int i = 0; i < wrappedArray.length; i++)
    array[i] = wrappedArray[i].intValue();
  return array;
}

确实,如果我知道需要一个Integer [],那么我应该知道如何创建int []。更新问题以反映我的拥有情况。我只知道它是包装类数组,并且我可以通过反射获得类本身和与之关联的原始类型。 - rid
我认为现在更好了,虽然由于自动装箱/拆箱,您不需要调用intValue()。您可以进行简单的赋值。 - Edwin Dalorzo

0

试试这个...

遍历wrappedArray中的每个元素并将其转换为原始int

class Test {



     public int[] toPrimitiveArray(Object[] wrappedArray) {

         int i = 0;
         int[] arr = new int[wrappedArray.length];

           for ( Object w : wrappedArray){


               arr [i] = (Integer) w;
                       i++;
           }

            return arr;
        }



        public static void main(String[] args){

            int[] a = new Test().toPrimitiveArray(new Integer[] { 1, 2, 3 });

            for (int b : a){

                System.out.println(b);
            }
        }


    }

编辑:

如果你需要将所有的包装类型转换为其相应的基本类型...

你需要使用 instanceof 来了解包装类型,然后将其转换为相应的基本类型。


该方法可以接受任何类型的包装器数组。更新问题。 - rid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接