5

If I have an array of instances of primitive wrapper classes, how can I obtain an array of their respective primitives?

Object toPrimitiveArray(Object[] wrappedArray) {
    return ?;
}

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

In the above example, I'd like toPrimitiveArray() to return an int[] containing the int values 1, 2, and 3.

rid
  • 61,078
  • 31
  • 152
  • 193
  • `final int[] ret = new int[wrappedArray.length]; int i=0; for (int w : wrappedArray) ret[i++] = w; return ret;` – Marko Topolnik Jul 15 '12 at 14:52
  • @MarkoTopolnik, updated question to reflect what I have. I know that it receives an array of primitive wrapper classes. I can obtain the actual class and the associated primitive type with reflection. – rid Jul 15 '12 at 14:55
  • There is no automatic way from `Integer.class` to `int[]`. You'll have to do that conversion explicitly for each type. You also need to call a different method for each wrapper type that extracts the primitive value. You'll either end up with miserably slow, convoluted reflection spaghetti, or with fast, repetitive literal code. – Marko Topolnik Jul 15 '12 at 15:08
  • For ArrayList input instead: http://stackoverflow.com/questions/718554/how-to-convert-an-arraylist-containing-integers-to-primitive-int-array – Ciro Santilli OurBigBook.com Mar 26 '15 at 14:10

4 Answers4

2

The problem is that your method cannot know what type of Number is being contained by the array, because you have defined it only as an array of Object, with no further information. So it's not possible to automatically produce a primitive array without losing compile-time type safety.

You could use reflection to check the Object type:

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 . . .

However, this is ugly and does not allow the compiler to check for type safety in your code, so increases the chance of error.

Could you switch to using a List of Number objects instead of an array? Then you could use type parameters (generics) to guarantee type safety.

Bobulous
  • 12,967
  • 4
  • 37
  • 68
  • It can contain any wrappers, not only numbers. It can, for example, contain an array of instances of the Character wrapper. Before calling the method though, I know for sure that an array of wrappers will be passed. – rid Jul 15 '12 at 14:57
  • Type safety is OP's least problem. – Marko Topolnik Jul 15 '12 at 15:24
1

How about this:

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;
}
vainolo
  • 6,907
  • 4
  • 24
  • 47
  • Indeed, if I know that it takes an `Integer[]`, I should know how to create the `int[]`. Updated question to reflect what I have. I just know that it's an array of wrapper classes, and I can, through reflection, obtain the class itself and the primitive type associated with it. – rid Jul 15 '12 at 14:55
  • I think it's better now, although thanks to autoboxing/unboxing, you don't need to invoke `intValue()`. You could do a simple assingment. – Edwin Dalorzo Jul 23 '12 at 06:29
1

This answer is quite late, but hopefully it helps future visitors to this questions. My take on a reflective solution can be improved but the basic idea is this:

@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;
}

Then use as following:

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(", ");
}

This prints out:

[true, false, true, true, false]
true, false, true, true, false,

This utility helps us pull arrays out of java.sql.Array, because java.sql.Array only gives us an Object for the array.

akagixxer
  • 1,767
  • 3
  • 21
  • 35
0

Try this....

Iterate through each element in wrappedArray and convert it into primitive 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);
            }
        }


    }

Edited:

If you need to convert all the Wrapper type to its respective primitive type..

You need to use instanceof to know the Wrapper type, then convert it into its respective primitives.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75