Which one is better and why ?
a) List<String> list = new ArrayList<>();
b) ArrayList<String> list = new ArrayList<>();
Which one is better and why ?
a) List<String> list = new ArrayList<>();
b) ArrayList<String> list = new ArrayList<>();
It depends on the context.
If you care only about the list semantics and not for the particular implementation, go for List<String>
. If you want to enforce a particular implementation, go for ArrayList<String>
, LinkedList<String>
or anything else.
In most cases, you will want to go on with the interface and not the particular implementation.
(a) is better because it is more flexible. If for example, suddenly your requirement changes and says "Instead of creating a new empty array list to assign to the variable list
, we will populate the list
with items filtered from another list", you need to change your code for that. You might change it to something like this:
List<String> list = anotherList.stream().filter(x -> x.length() > 2).collect(Collectors.toList());
Since collect(Collectors.toList())
returns a List
, you also need to change the type of list
if you were using the code in (b).
Another situation is that later on you found out that you need to assign some other kind of list e.g. LinkedList
to list
. If you were using the code in (a), you can just assign the linked list straight away. If you were using the code in (b), you will have to go back to the declaration of list
and change the type.
The general pattern is that as you use more "abstract" types, your code becomes more flexible but at the same time you can do less with your variables. For example, you can't use methods declared only in ArrayList
on your list
variable, but on the other hand, other kinds of lists can be assigned to list
. If you an even more abstract type, Collection
, then you can't use the members only declared in List
anymore, but then all kinds of collections - Set
, Map
etc - can be assigned.