15

Why I can initialize ArrayList, like this:

ArrayList<Integer> x = new ArrayList<Integer>(Arrays.asList(1,2));

But got Error when using:

ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1,2));
3
  • 1
    numbers by default are int so when java tries to auto-box 1 and 2 it will turn it into wrapper type Integer and Integer isn't the same or any how related to Long Commented Oct 4, 2017 at 12:30
  • 6
    Arrays.asList(1L, 2L) Commented Oct 4, 2017 at 12:30
  • 1
    1,2 are ints and no longs Commented Oct 4, 2017 at 12:30

4 Answers 4

35

Explanation

Java automatically transforms int to long if needed.

However, Java does not do the same if a transformation from Integer to Long is needed.

The function Arrays.asList(...) returns a List<E> with E being the type used as parameters. As you use 1, 2, 3 the type is int. However the generic usage of data-types as List<int> is not possible in Java (at least currently). Therefore it automatically transforms int to Integer and produces a List<Integer> object. This process is called auto-boxing, Java can do this for all data-types to their corresponding object representation.

If you now use the constructor new ArrayList<Integer>(List<E> list) it expects E to be something of type Integer. So a List<Integer> works as input.

But when you use new ArrayList<Long>(List<E> list) obviously E needs to be of type Long. However the object Integer is not of type Long thus it does not accept the parameter. The first common type of Integer and Long is the abstract class Number (which also holds Double, Float and others) (documentation).


Solution

So it all revolves around the input 1, 2, 3 being interpreted as int instead of long. You can fix this by explicitly telling Java to interpret the numbers as long, you do so by appending l or L after the number:

new ArrayList<Long>(Arrays.asList(1L, 2L, 3L));

Now you receive a List<Long> which then is added to an ArrayList<Long>.


Note that the same technique can be used to explicitly interpret decimal numbers as float instead of double: 1.5F or 1.5f

Sign up to request clarification or add additional context in comments.

2 Comments

It's important to note that asList returns a custom fixed size ArrayList and not java.util.ArrayList.
@Oleg You are right, did not know that. I'll remove the note from the answer as it's not that useful then.
14

That's because 1 and 2 are ints and Arrays.asList(1, 2) creates a List<Integer>.

And the copy constructor of ArrayList requires the argument to be of the same generic type.

You have several options but the simplest one is to change the ints into longs by adding a L suffix:

List<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));

Note that with Java 9 you can also write:

List<Long> x = List.of(1L, 2L);

2 Comments

It might be woth mentioning that the java 9 version is similar to Arrays.asList in that it returns an immutable List - if you want x to be mutable, you still need the copy constructor.
Just to avoid confusion - I'm aware that the list returned by Arrays.asList is mutable, but fixed size. The answers to this question might also be of interest for future readers.
14

You have to specify a Long number using literal l or L.

List<Long> x = new ArrayList<Long>(Arrays.asList(1L, 2L));

Otherwise 1 and 2 are understood as integers resulting in List<Integer>.

Comments

4

Because Arrays.asList(1,2) will implicitly return a List<Integer>.

You can fix this by using the following idiom:

ArrayList<Long> x = new ArrayList<Long>(Arrays.asList(1l,2l));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.