4

Possible Duplicate:
Converting an array of objects to an array of their primitive types

I making a Parcel for Android and I'm trying to package an ArrayList<Long> (toArray gives me Long[]) by converting it to long[], is there a simple way to do this?

I realize I can loop through but I guess I'm looking for a more elegant solution.

Community
  • 1
  • 1
Emil Davtyan
  • 13,808
  • 5
  • 44
  • 66

3 Answers3

11

You could use Apache commons ArrayUtils:

long[] longArray = ArrayUtils.toPrimitive(longObjectArray);

or in Google's Guava:

long[] longArray = Longs.toArray(Arrays.asList(longObjectArray));
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • 1
    Nice, but I wouldn't include a whole new jar to my project just to avoid implementing one simple loop myself. – Ridcully Nov 24 '12 at 18:13
  • 5
    @Ridcully once you include it, you'll probably find yourself using it again and again. It's full of useful, *common* (hence the name) methods that reduces the amount of tedious boilerplate code. – Phil K Nov 24 '12 at 18:20
  • Thanks for the tip, but I agree with Ridcully I try to keep the APK as small as possible. – Emil Davtyan Nov 24 '12 at 18:28
  • 1
    You could always just copy that particular method in, making sure to keep a note where it's from (and even keeping the package the same org.apache...) It is Apache licensed after all. http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/ArrayUtils.java?view=markup#l2885 Then if (when) you DO decide to include the whole thing, easy switch :) – Jason Dunkelberger Nov 24 '12 at 18:35
  • In that case I would rather recommend guava. – assylias Nov 24 '12 at 18:38
  • If APK size is your concern, you should be using Proguard anyway. – Louis Wasserman Nov 24 '12 at 19:56
  • @PhilKeeling I agree -- would be nice if some commons libraries were part of Android SDK. – Ridcully Nov 24 '12 at 20:06
6

Unfortunately there is no easier way than looping. This post is about doing the opposite but the idea is the same...

Since another answer recommends Apache Commons and you are on Android - if I were to include an additional dependency I would rather go for guava Longs utility class:

long[] primitive = Longs.toArray(listOfLongObjects);

For reference, the code is:

  public static long[] toArray(Collection<? extends Number> collection) {
    if (collection instanceof LongArrayAsList) {
      return ((LongArrayAsList) collection).toLongArray();
    }

    Object[] boxedArray = collection.toArray();
    int len = boxedArray.length;
    long[] array = new long[len];
    for (int i = 0; i < len; i++) {
      // checkNotNull for GWT (do not optimize)
      array[i] = ((Number) checkNotNull(boxedArray[i])).longValue();
    }
    return array;
  }
Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
2

Long and long are different types. Long is a class. long is a primitive. Autoboxing introduced to java 5 can confuse some people because bi-directional transformation between Long and long is done automatically by compiler. However this is not correct for arrays. This means that you have to create new array of type long and copy element-by-element:

List<Long> list = new ArrayList<>();
// this way you create array of Long
Long[] arr1 = list.toArray(new Long[list.size()]);

// this way you create array of long
long[] arr2 = new long[list.size()];
int i = 0;
for (Long e : list) {
    arr2[i++] = e; // autoboxing does the job here
}

Obviously you can use System.arrcopy() instead of writing loop yourself. However id does not make any difference.

AlexR
  • 114,158
  • 16
  • 130
  • 208