ArrayList or List declaration in Java
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
.
Initialization of an ArrayList in one line
Actually, probably the "best" way to initialize the ArrayList
is the method you wrote, as it does not need to create a new List
in any way:
ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
The catch is that there is quite a bit of typing required to refer to that list
instance.
There are alternatives, such as making an anonymous inner class with an instance initializer (also known as an "double brace initialization"):
ArrayList<String> list = new ArrayList<String>() {{
add("A");
add("B");
add("C");
}};
However, I'm not too fond of that method because what you end up with is a subclass of ArrayList
which has an instance initializer, and that class is created just to create one object -- that just seems like a little bit overkill to me.
What would have been nice was if the Collection Literals proposal for Project Coin was accepted (it was slated to be introduced in Java 7, but it's not likely to be part of Java 8 either.):
List<String> list = ["A", "B", "C"];
Unfortunately it won't help you here, as it will initialize an immutable List
rather than an ArrayList
, and furthermore, it's not available yet, if it ever will be.
How to declare an ArrayList with values?
In Java 9+ you can do:
var x = List.of("xyz", "abc");
// 'var' works only for local variables
Java 8 using Stream
:
Stream.of("xyz", "abc").collect(Collectors.toList());
And of course, you can create a new object using the constructor that accepts a Collection
:
List<String> x = new ArrayList<>(Arrays.asList("xyz", "abc"));
Tip: The docs contains very useful information that usually contains the answer you're looking for. For example, here are the constructors of the ArrayList
class:
ArrayList()
Constructs an empty list with an initial capacity of ten.
ArrayList(Collection<? extends E> c)
(*)Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.
ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.
What is the difference between three types of declaration of array list and why we write the interface first then on other side implementing class?
a)List l = new ArrayList<String>();
is the same as List<Object> l = new ArrayList<String>();
. It means that the variable l
is a list that can store any Object
, but not only a String. Also you will need to cast the values of the list if you want to use them as Strings. So the following code would compile (which is usually not what you want):
List l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//adding an int is not realy expected here, but works
l.add(new Date());//also adding any other object is allowed
String s = (String) l.get(0);//s will be "a string"
String s2 = (String) l.get(1);//runtime error, since 42 can't be cast into a String
b)List<String> l=new ArrayList<String>();
means, that the variable l
is a list of Strings and will only accept String values. The following code would cause compiler errors:
List<String> l = new ArrayList<String>();
l.add("a string");//adding a String type is what is expected here
l.add(42);//compiler error
l.add(new Date());//compiler error
c)List<String> l=new ArrayList<>();
is basically the same as List<String> l=new ArrayList<String>();
. The diamond operator <>
just means that it should be clear to the compiler, which type is used here, so the programmer can be lazy and let the compiler do the work.
p)List<String>l = new ArrayList<String>();
tells the compiler, that l is of type List. So if you want to assign an ArrayList
to the variable l, that is allowed, and if you then decide, that a LinkedList
is better, you can still assign a LinkedList
and it will still work, because LinkedList
and ArrayList
both implement the interface List
. So the follwing code will work:
List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();
//use the List l like nothing has changed. You just don't need to care.
q)ArrayList<String> l= new ArrayList<String>();
means, that the variable l
is an ArrayList
and can never be any other List
implementation (like a LinkedList
), so you can't change the implementation easily. Therefore the following code will not compile:
List<String> l = new ArrayList<String>();
//later on you decide to change the type (maybe for a better performance or whatever)
l = new LinkedList<String>();//compiler error; now you need to change many parts of your code if you still want to change the type of l to a LinkedList
Therefore usually p is the better solution, because you can change the code easily. Only of you need to call methods that are not part of the List interface, like the trimToSize method of ArrayList
it can be needed to use q. But that's a very rare case.
Summary:
In almost every case it's better to use p than q.
Also in almost every case it's better to use b or c than a. Whether you use b or c doesn't realy matter that much. c is just a bit shorter.
Difference of List and ArrayList in declaration?
The first declaration lets you program to interface. It ensures that later on you can safely replace ArrayList
with, say, LinkedList
, and the rest of code is going to compile.
The second declaration lets you program to the class, so you could potentially use methods of ArrayList
which do not implement the List
interface. For example, you can call ensureCapacity()
on the list declared as ArrayList
, but not on a list declared as List
. Although generally programming to interface should be preferred, there is nothing wrong with doing it if you must call class-specific methods: for example, ability to call ensureCapacity()
could save some unnecessary reallocations if you know the new target size of your list.
What are the List or ArrayList declaration differences in Java?
The first one is only valid since Java 7, and is the equivalent of
List<String> list = new ArrayList<String>();
It's just less verbose.
Same for the third one, which is equivalent to
ArrayList<String> list = new ArrayList<String>();
and thus strictly equivalent to the second one.
You should prefer the first one, for the reasons mentioned in the answers to the following question: List versus ArrayList as reference type?
Polymorphism: Why use List list = new ArrayList instead of ArrayList list = new ArrayList?
The main reason you'd do this is to decouple your code from a specific implementation of the interface. When you write your code like this:
List list = new ArrayList();
the rest of your code only knows that data is of type List
, which is preferable because it allows you to switch between different implementations of the List
interface with ease.
For instance, say you were writing a fairly large 3rd party library, and say that you decided to implement the core of your library with a LinkedList
. If your library relies heavily on accessing elements in these lists, then eventually you'll find that you've made a poor design decision; you'll realize that you should have used an ArrayList
(which gives O(1) access time) instead of a LinkedList
(which gives O(n) access time). Assuming you have been programming to an interface, making such a change is easy. You would simply change the instance of List
from,
List list = new LinkedList();
to
List list = new ArrayList();
and you know that this will work because you have written your code to follow the contract provided by the List
interface.
On the other hand, if you had implemented the core of your library using LinkedList list = new LinkedList()
, making such a change wouldn't be as easy, as there is no guarantee that the rest of your code doesn't make use of methods specific to the LinkedList
class.
All in all, the choice is simply a matter of design... but this kind of design is very important (especially when working on large projects), as it will allow you to make implementation-specific changes later without breaking existing code.
Should I declare/Initialize ArrayLists as Lists, ArrayLists, or ArrayLists of Cat
You should declare it as a List<Cat>
, and initialize it as an ArrayList<Cat>
.
List
is an interface, and ArrayList
is an implementing class. It's almost always preferable to code against the interface and not the implementation. This way, if you need to change the implementation later, it won't break consumers who code against the interface.
Depending on how you actually use the list, you might even be able to use the less-specific java.util.Collection
(an interface which List
extends).
As for List<Cat>
(you can read that as "list of cat") vs List
: that's Java's generics, which ensure compile-time type safely. In short, it lets the compiler make sure that the List
only contains Cat
objects.
public class CatHerder{
private final List<Cat> cats;
public CatHerder(){
this.cats = new ArrayList<Cat>();
}
}
Type List vs type ArrayList in Java
Almost always List
is preferred over ArrayList
because, for instance, List
can be translated into a LinkedList
without affecting the rest of the codebase.
If one used ArrayList
instead of List
, it's hard to change the ArrayList
implementation into a LinkedList
one because ArrayList
specific methods have been used in the codebase that would also require restructuring.
You can read about the List
implementations here.
You may start with an ArrayList
, but soon after discover that another implementation is the more appropriate choice.
Related Topics
Finding Number of Cores in Java
Difference Between One-To-Many, Many-To-One and Many-To-Many
Passing Pointers Between C and Java Through Jni
Writing a Large Resultset to an Excel File Using Poi
Pass a Local File in to Url in Java
How to Create a Class Literal of a Known Type: Class<List<String>>
Could Not Find Method Compile() for Arguments Gradle
Can Anyone Recommend a Simple Java Web-App Framework
How to Create a Modular Jsf 2.0 Application
Best Way to Create Enum of Strings
Performance Considerations for Keyset() and Entryset() of Map
Exception in Thread 'Main' Java.Lang.Noclassdeffounderror:
String.Format() to Format Double in Java
"File Not Found" When Running New Libgdx Project