13

What is best way recopying int[] array elements into ArrayList?

I need to do this fast so what would be the fastest way?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Streetboy
  • 4,351
  • 12
  • 56
  • 101
  • 2
    Hm, isn't `Arrays.asList` sufficient? – Niklas B. Apr 22 '12 at 15:37
  • 2
    *"I need to do this fast"* Fast in typing the code or fast in execution? The latter should be tested at run-time, but given the deep amount of thought/research that seemed to go into the question, I suspect you mean the former. – Andrew Thompson Apr 22 '12 at 15:44

4 Answers4

19

ArrayList is not the best storage for primitives such as int. ArrayList stores objects not primitives. There are libraries out there for Lists with primitives. If you really want to store all primitive int as anInteger object you will have to convert them one by one using Integer.valueOf(...) (so you don't create extra Integer instances when not needed).

While you can do this:

List<Integer> list = Arrays.asList(1, 2, 3);

You cannot do this:

int[] i = { 1, 2, 3 };
List<Integer> list = Arrays.asList(i); // this will get you List<int[]>

as an array is actually an object as well an treated as such in var-args when using primitives such as int. Object arrays works though:

List<Object> list = Arrays.asList(new Object[2]);

So something along the lines of:

int[] array = { 1, 2, 3 };
ArrayList<Integer> list = new ArrayList<Integer>(array.length);
for (int i = 0; i < array.length; i++)
  list.add(Integer.valueOf(array[i]));
Mattias Isegran Bergander
  • 11,811
  • 2
  • 41
  • 49
13

Use Arrays#asList(T... a) to create "a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.)"

Integer[] intArray = {1, 2, 3, 42}; // cannot use int[] here
List<Integer> intList = Arrays.asList(intArray);

Alternatively, to decouple the two data structures:

List<Integer> intList = new ArrayList<Integer>(intArray.length);

for (int i=0; i<intArray.length; i++)
{
    intList.add(intArray[i]);
}

Or even more tersely:

List<Integer> intList = new ArrayList<Integer>(Arrays.asList(intArray));
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 1
    `new ArrayList();` could be `new ArrayList(intArray.length);` to avoid reallocate array – Pau Kiat Wee Apr 22 '12 at 15:43
  • 5
    Pulsar has a point: This doesn't work because `Arrays.asList(intArray)` returns `List`. So it seems we actually have to use a loop here, or can we somehow convert an `int[]` into an `Integer[]` array? – Niklas B. Apr 22 '12 at 15:59
  • @NiklasB. indeed. Edited; `Integer[]` instead of `int[]` will do the trick. – Matt Ball Apr 22 '12 at 16:03
  • 9
    Well yeah, but the question was about an `int[]` array specifically :) But of course OP can just skip the first sample if it doesn't work him/her. – Niklas B. Apr 22 '12 at 16:04
  • @MattBall Does your last method actually work? for `List li = Arrays.asList(intArray);` I get `Type mismatch: cannot convert from List to List` – likejudo May 13 '14 at 19:54
  • @likejiujitsu you missed a spot. Read carefully. – Matt Ball May 13 '14 at 20:08
  • The last line is misleading. Firstly you don't need new ArrayList if you already dealing with Integer, not int, and secondly that is the whole point - the question is about int[], not Integer[] – yname Dec 01 '17 at 14:45
6

With Guava, you don't need to bother with the Integer[]:

int[] array;
List<Integer> list = Ints.asList(array);

and if you want an ArrayList, that's just

List<Integer> list = Lists.newArrayList(Ints.asList(array));

(Disclosure: I contribute to Guava.)

Otherwise, if all you have is an int[], you have to do it the old-fashioned way:

int[] array;
List<Integer> list = new ArrayList<>(array.length);
for (int val : array) {
  list.add(val);
}
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
2

I'll provide an alternate answer as well, depending on how the List is used this could perform better (creation is faster, and only the actually used ints are converted, but they are always converted not just the first time, so repeated get of the same element is worse). Create a simple wrapper list around the array:

final int[] array = {1, 2, 3};
List list = new AbstractList<Integer>() {

     public Integer get(int index) {
       return array[index];
     }

     public Integer set(int index, Integer value) {
       //or just throw new UnsupportedOperationException("..."); if not needed
       Integer old = array[index];
       array[index] = value;
       return old;
     }

     public int size() {
       return array.length;
     }
};

or in a method creating it for you:

static List<Integer> asList(final int[] array) {
  return new AbstractList<Integer>() { ...
             };
}
Mattias Isegran Bergander
  • 11,811
  • 2
  • 41
  • 49