Arrays.asList() not working as it should?

38,084

Solution 1

How about this?

Integer[] ints = new Integer[] {1,2,3,4,5};
List<Integer> list = Arrays.asList(ints);

Solution 2

There's no such thing as a List<int> in Java - generics don't support primitives.

Autoboxing only happens for a single element, not for arrays of primitives.

As for how to correct it - there are various libraries with oodles of methods for doing things like this. There's no way round this, and I don't think there's anything to make it easier within the JDK. Some will wrap a primitive array in a list of the wrapper type (so that boxing happens on access), others will iterate through the original array to create an independent copy, boxing as they go. Make sure you know which you're using.

(EDIT: I'd been assuming that the starting point of an int[] was non-negotiable. If you can start with an Integer[] then you're well away :)

Just for one example of a helper library, and to plug Guava a bit, there's com.google.common.primitive.Ints.asList.

Solution 3

Because java arrays are objects and Arrays.asList() treats your int array as a single argument in the varargs list.

Solution 4

Enter Java 8, and you can do following to collect in a boxed Array:

Integer[] boxedInts = IntStream.of(ints).boxed().toArray(Integer[]::new);

Or this to collect in a boxed List

List<Integer> boxedInts = IntStream.of(ints).boxed().collect(Collectors.toList());

However, this only works for int[], long[], and double[]. This will not work for byte[].

Note that Arrays.stream(ints) and IntStream.of(ints) are equivalent. So earlier two examples can also be rewritten as:

Integer[] boxedIntArray = Arrays.stream(ints).boxed().toArray(Integer[]::new);
List<Integer> boxedIntList = Arrays.stream(ints).boxed().collect(Collectors.toList());

This last form could be favored as it omits a primitive specific subtype of Stream. However, internally it is still a bunch of overloaded's which in this case still create a IntStream internally.

Solution 5

The problem is not with Arrays.asList(). The problem is that you expect autoboxing to work on an array - and it doesn't. In the first case, the compiler autoboxes the individual ints before it looks at what they're used for. In the second case, you first put them into an int array (no autoboxing necessary) and then pass that to Arrays.asList() (not autoboxing possible).

Share:
38,084
Mohammad Taha
Author by

Mohammad Taha

Android geek, TDD nut, International Speaker, ex Shazamer, currently the Principal Software Engineer for Apps at ASOS. Noti.st | Twitter | LinkedIn | GitHub

Updated on July 05, 2022

Comments

  • Mohammad Taha
    Mohammad Taha almost 2 years

    I have a float[] and i would like to get a list with the same elements. I could do the ugly thing of adding them one by one but i wanted to use the Arrays.asList method. There is a problem though. This works:

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

    But this does not.

    int[] ints = new int[] {1,2,3,4,5};
    List<Integer> list = Arrays.asList(ints);
    

    The asList method accepts a varargs parameter which to the extends of my knowledge is a "shorthand" for an array.

    Questions:

    • Why does the second piece of code returns a List<int[]> but not List<int>.

    • Is there a way to correct it?

    • Why doesn't autoboxing work here; i.e. int[] to Integer[]?

  • palantus
    palantus over 14 years
    Beat me, but it would be better with an explanation also.
  • Mohammad Taha
    Mohammad Taha over 14 years
    unbelievable... It works with reference but not with primitive types :D thanks a lot. :)
  • Mohammad Taha
    Mohammad Taha over 14 years
    Hm but is there an easy way to convert an int[] to Integer[]? The thing is i get my array via a method call and i cannot change it.
  • whiskeysierra
    whiskeysierra about 14 years
    @mmyers In fact, that's what this question is all about. +1 for ChssPly76
  • Jonik
    Jonik almost 14 years
    @Savvas: See stackoverflow.com/questions/880581/java-convert-int-to-integ‌​er or Jon Skeet's answer here. Libraries like Apache Commons Lang or Guava will be of some help.
  • Geek
    Geek over 10 years
    Why does "Autoboxing only happens for a single element, not for arrays of primitives.". What do you think is the reason for this design decision?
  • Jon Skeet
    Jon Skeet over 10 years
    @Geek: Well what would you suggest as an alternative? It would be odd for a double[] to be automatically converted to a Double[] by copying all the elements - such that a cast of a reference type would effectively clone the data, unlike every other operation in Java. If you're suggesting that a Double[] should be able to be backed by a double[] in a "view" sort of way, that has other issues such as how you store null references and again the difference between this and other arrays. I think it was the right decision.
  • marcinj
    marcinj about 10 years
    with java 8 you can use stream api: List<Integer> list = Arrays.stream(new int[]{1,2,3}).boxed().collect(Collectors.toList());, a bit verbose though
  • Maarten Bodewes
    Maarten Bodewes over 9 years
    One of these Guava functions that should have been added to Java a long way back. Horrible type juggling with primitive types is unfortunately not going away soon.
  • karl
    karl over 8 years
    Warning: lists returned by Ints.asList do not support add() or related methods
  • laertis
    laertis about 6 years
    You need to cast the result from toArray() since it returns Object[]
  • laertis
    laertis about 6 years
  • YoYo
    YoYo about 6 years
    Ok. You are right. Type at that point is Stream<Integer> and not IntStream. I have fixed it however by using toArray(Integer[]::new) instead. Maybe simply typecasting here would be better?
  • laertis
    laertis about 6 years
    This is actually a different overloaded toArray() implementation (docs.oracle.com/javase/8/docs/api/java/util/stream/…) that uses a generator function and does the job properly. It's better to avoid typecasting where you can..
  • user7294900
    user7294900 almost 5 years
    Can warning be overcome Type safety: The expression of type List needs unchecked conversion to conform to List<Integer> ?
  • Abdul
    Abdul almost 5 years
    Array.asList works only with Objects? Not Primitive array?