ArrayList or List declaration in Java
What is the difference between these two declarations?
Declaration 1:
ArrayList<String> arrayList = new ArrayList<String>();
Declaration 2:
List<String> arrayList = new ArrayList<String>();
Solution 1:
List<String> arrayList = new ArrayList<String>();
Is generic where you want to hide implementation details while returning it to client, at later point of time you may change implementation from ArrayList
to LinkedList
transparently.
This mechanism is useful in cases where you design libraries etc., which may change their implementation details at some point of time with minimal changes on client side.
ArrayList<String> arrayList = new ArrayList<String>();
This mandates you always need to return ArrayList
. At some point of time if you would like to change implementation details to LinkedList
, there should be changes on client side also to use LinkedList
instead of ArrayList
.
Solution 2:
List
is an interface and ArrayList
is an implementation of the List interface. The ArrayList
class has only a few methods(i.e clone(), trimToSize(), removeRange() and ensureCapacity())
in addition to the methods available in the List interface. There is not much difference in this.
1. List<String> l = new ArrayList<>();
2. ArrayList<String> l = new ArrayList<>();
If you use the first, you will be able to call the methods available in the List interface and you cannot make calls to the new methods available in the ArrayList
class. Where as, you are free to use all the methods available in the ArrayList
if you use the second one.
I would say the first approach is a better one because, when you are developing java applications, when you are supposed to pass the collection framework objects as arguments to the methods, then it is better to go with first approach.
List<String> l = new ArrayList<>();
doSomething(l);
In future due to performance constraints, if you are changing the implementation to use LinkedList
or someother classes which implements List
interface, instead of ArrayList
, you need to change at one point only(the instantiation part).
List<String> l = new LinkedList<>();
Else you will be supposed to change at all the places, wherever, you have used the specific class implementation as method arguments.
Solution 3:
The difference is that variant 1 forces you to use an ArrayList
while variant 2 only guarantees you have anything that implements List<String>
.
Later on you could change that to List<String> arrayList = new LinkedList<String>();
without much hassle. Variant 1 might require you to change not only that line but other parts as well if they rely on working with an ArrayList<String>
.
Thus I'd use List<String>
in almost any case, except when I'd need to call the additional methods that ArrayList
provides (which was never the case so far): ensureCapacity(int)
and trimToSize()
.
Solution 4:
The first declaration has to be an ArrayList, the second can be easily changed to another List type. As such, the second is preferred as it make it clear you don't require a specific implementation. (Sometimes you really do need one implementation, but that is rare)