gbtimmon
gbtimmon

Reputation: 4332

new ArrayList<T> (T[] arr)

Okay So this doesnt make sense to me.... maybe someone can shed some light. A technique I figure out for converting primitive arrays into ArrayLists is as follows.

arr = new ArrayList<String>(Arrays.asList(primitveArray));

this works quit well. But today, I start wondering how efficent this was, since I happened to be writing some code where performance is more important then It had been in other applications I had worked on in the past and decided to look at the source code for Arrays.asList()

I found this:

public static <T> List<T> asList(T... array) {
    return new ArrayList<T>(array);
}

And I said to myself: "Im such an idiot, Its just passing the array into the ArrayList constructor ArrayList<T>(T[] arr), why dont I just skip a step and not use the stupid Arrays.asList?

So i try this

arr = new ArrayList<T>(primitveArray)

in my code. But then suddenly ArrayList<T>(T[] arr) is undefined. Im quite confused why this would be?

Upvotes: 4

Views: 949

Answers (6)

Jeshurun
Jeshurun

Reputation: 23186

So i try this arr = new ArrayList<T>(primitveArray)

T is a generically typed parameter, you cannot use it when instanciating an ArrayList, only when declaring its use in a Class or method. Instead, change your code to:

arr = Arrays.asList(primitveArray);

The ArrayList class used in the Arrays class is different from the ArrayList class you use in your code, it is an inner class defined in the Arrays class itself, and defines a constructor taking an Array as an argument. Since this class is private, with a non-public constructor, it can only be instanciated and used within the Arrays class itself.

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] array) {
            if (array==null)
                throw new NullPointerException();
        a = array;
    }

...

Upvotes: 2

trutheality
trutheality

Reputation: 23465

I guess the question reamins now, why the would do this.

The List returned by Arrays.asList (an Arrays.ArrayList). Is a view of the original array. If you change it, the array changes, if you change the array, it changes. If you try to do anything that resizes it, it throws an exception, because you can't resize primitive arrays.

It's just an adapter to efficiently treat the primitive array as a List without having to copy the elements into a new implementation of List.

When you do

new java.util.ArrayList( Arrays.asList( primitiveArray ) );

is when you are copying the elements. The result is not a view, but is independent of the original array. And also, you gained the ability to resize it. If you look at the source code (you have to look at both java.util.ArrayList and Arrays.ArrayList, you can see that it's copying those elements in the most efficient way possible, from the original primitive array into the array that is backing the java.util.ArrayList, so there is no loss of efficiency to worry about.

Upvotes: 1

Marko Topolnik
Marko Topolnik

Reputation: 200196

The most important thing for you to realize is that Arrays.asList is utterly performant, it's O(1) with a very small fixed overhead. This is because no data is being copied. It just gives your array a List interface to interact with it. Second, the private static class ArrayList is indeed very important since the public class ArrayList does copy the data and results in performance degradation.

Upvotes: 1

josefx
josefx

Reputation: 15656

I guess the question reamins now, why the would do this

The returned list is a view of the array, no copy takes place and any change to the list is visible in the source array. Since it is allways backed by the source array any modifications affecting the lists size are unsupported and throw an exception.

Upvotes: 1

gbtimmon
gbtimmon

Reputation: 4332

Okay so about ten secounds after asking this questions I figured it out. Apprently java.util.Arrays implements a static local class called ArrayList which is seperate than java.util.ArrayList. Confusingly enough they are both named ArrayList, but where as java.util.Arrays.ArrayList is declared as

private static class ArrayList<E> extends AbstractList<E> implements
        List<E>, Serializable, RandomAccess

java.util.ArrayList is declared as

public class ArrayList<E> extends AbstractList<E> implements List<E>,
    Cloneable, Serializable, RandomAccess 

I guess the question reamins now, why the would do this. Probably optimization I suppose. Since Array is casting the ArrayList to a List it only need to support just enough to perform the List operation without the rest of the ArrayLists normal functionality.

Upvotes: 2

NPE
NPE

Reputation: 500663

But then suddenly ArrayList<T>(T[] arr) is undefined. I'm quite confused why this would be?

There are two classes named ArrayList:

  • one is a private static inner class of java.util.Arrays;
  • the other is java.util.ArrayList.

asList() uses the former. You are trying to use the latter. The two classes are unrelated, they just happen to share the same name.

It is important to note that java.util.Arrays.ArrayList does not copy the array. It provides a view onto it.

Upvotes: 5

Related Questions