1. Introduction
This article is part of the ArrayList class series. In this article, we will look at 3 different constructors provided in the ArrayList class.
ArrayList class is a better form of an array. ArrayList is an array, but a resizable one, with a rich set of methods.
A little about ArrayList.
- Resizable array
- ArrayList is a resizable array. As you add the elements in the ArrayList, it grows internally to accommodate those elements. Converse is not true as of JDK 12 i.e. if you delete an element from ArrayList, it doesn’t automatically shrink the size of ArrayList. You can manually shrink the size using trimToSize() method.
- Insertion order
- ArrayList always maintains Insertion order of elements. Which means if you iterate through the List, it will retrieve the elements in the same order we inserted them.
- Positional/Index Access
- We know arrays for its index access, so you can access the element in O(1) time. You can achieve the same in ArrayList using get(index) method.
- Duplicate elements allowed
- ArrayList allows duplicate elements. It doesn’t check if elements exist. It will just append the element it got.
- Not thread safe
- ArrayList is not a thread safe class. So it is not an ideal candidate to use in a multithreaded environment if data in ArrayList needs to be manipulated.
2. Content
We will look at the working of all these constructors with examples.
public ArrayList() public ArrayList(int initialCapacity) public ArrayList(Collection<? extends E> c)
The ArrayList’s class hierarchy looks like this :
3. public ArrayList()
This constructor is used to create an ArrayList with no specification for the underlying array. Remember, ArrayList is a smart wrapper on the array itself.
In fact, this constructor is the most used constructor while creating the ArrayList. Let us create an ArrayList of String.
List<String> names = new ArrayList<>(); names.add("John"); names.add("Jane");
So in this example, we created the ArrayList called names. It will hold String elements. We added two distinct elements called John and Jane.
Internal of ArrayList :
When we add the first element in ArrayList, the underlying implementation of ArrayList creates an array of 10 elements.Â
What happens after we add 10 elements? Well, the underlying implementation will allocate a new array of size roughly 1.5 times the original array and copy all elements from the old array to the new one. You don’t have to deal with the internal implementation.Â
This is the most popular constructor as it is simple to use. Let us look at two other constructors.
4. public ArrayList(int initialCapacity)
ArrayList(int initialCapacity) is used to create an ArrayList with an underlying array size equal to initialCapacity.
- If the value of initialCapacity is < 0 or is a negative number, then the constructor throws IllegalArgumentException.
- If the value of initialCapacity is equal to 0, then it behaves the same as the public ArrayList() constructor.
- If the value of initialCapacity is greater than 0, then it creates the underlying array with a size equal to initialCapacity.
Let us take an example and understand it more.
List<String> names = new ArrayList<>(20); names.add("John"); names.add("Jane");
In this example, we created the ArrayList with an initialCapacity of 20 elements and added two elements. So the underlying array has a capacity of 20 elements. When we add the 21st element, it will create a new array roughly 1.5 times of the old array size. Once that is done, it copies all elements of the old array to the new array.
It may look like a good idea to use this constructor instead of public ArrayList() but we need to be careful. If we choose initialCapacity too low, then the ArrayList has to frequently create new arrays to accommodate more values. If you choose initialCapacity too high, then the ArrayList would be too large and it would waste space. We need delicate handling while using this constructor. If in doubt, use the public ArrayList() constructor. If you want to use this constructor, select proper initialCapacity after running benchmarks in junit.
5. public ArrayList(Collection<? extends E> c)
public ArrayList(Collection<? extends E> c) constructor acts as a bridge between other collections and ArrayList. Note that the parameter is Collection, so any implementation of Collection interface can be input of this constructor.
Assume that you have an instance of HashSet and want to convert that into ArrayList, you can just use this constructor.
If the input Collections is null, the constructor will throw NullPointerException.
Let us take an example :
Set<String> names = new HashSet<>(); names.add("Ned"); names.add("Catelyn"); List<String> list = new ArrayList<>(names); Assert.assertEquals(2, list.size());
We inserted HashSet as input to the constructor. ArrayList copy all elements from HashSet and insert in ArrayList. The HashSet remains unchanged as part of this call. ArrayList will just read the data from HashSet, it will not modify HashSet.
6. Conclusion
In this article we saw three different constructors of the ArrayList class.
- public ArrayList(): This is the most popular constructor and easy to use.Â
- public ArrayList(int initialCapacity): Creates an array with specified initialCapacity in parameter. Easy to use, but we need to be very careful with the initialCapacity parameter.
- public ArrayList(Collection<? extends E> c): This constructor acts as a bridge between collections and ArrayList.