Reputation: 4332
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
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
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
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
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
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 ArrayList
s normal functionality.
Upvotes: 2
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
:
private
static
inner class of java.util.Arrays
;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