I am a somewhat experienced Java developer and I keep seeing things like this
List<Integer> l = new ArrayList<Integer>(0);
which I really can't understand. What's the point of creating an ArrayList
with an initial capacity of 0, when you know it's going to grow beyond the capacity?
Are there any known benefits of doing this?
Another way to check if arraylist contains any element or not, we can check the size of arraylist. If the list size is greater than zero, then list is not empty. If list size is 0, list is empty.
An ArrayList has an initial capacity which is simply the size of the array used to store the elements in the list. When you create an ArrayList you can specify the initial capacity. For example: ArrayList<Integer> arrayList = new ArrayList<>(100);
Note that they counted starting from 0, not 1. You misunderstand the "size of the array is always one more than the number of elements." It's actually one more than the largest index.
Whenever an instance of ArrayList in Java is created then by default the capacity of Arraylist is 10. Since ArrayList is a growable array, it automatically resizes itself whenever a number of elements in ArrayList grow beyond a threshold.
It keeps the size (in memory) of the ArrayList
very small, and is a tactic for when you want the variable to be non-null and ready to use, but don't expect for the List
to be populated immediately. If you expect it to be populated immediately, it's best to give it a larger initial value - any "growing" of the ArrayList
is internally creating a new primitive array, and copying items over. Growth of an ArrayList
is expensive, and should be minimized.
Or, if you're creating lots of instances of a class that each contain one of these List
properties. If you don't immediately plan on filling them, you can save a bit of memory by not allocating the room just yet.
However: There is a better way: Collections.emptyList()
. Normally you'll want to protect access to that list directly, and (as an example) in your class provide domain-specific method calls that operate on the internal List
. For example, let's say you have a School
class that contains a List
of student names. (Keeping it simple, note this class is not thread safe.)
public class School {
private List<String> studentNames = Collections.emptyList();
public void addStudentName(String name) {
if (studentNames.isEmpty()) {
studentNames = new ArrayList<String>();
}
studentNames.add(name);
}
public void removeStudentName(String name) {
studentNames.remove(name);
if (studentNames.isEmpty()) {
studentNames = Collections.emptyList(); // GC will deallocate the old List
}
}
}
If you're willing to make the isEmpty()
checks and perform the initialization/assignment, this is a better alternative to creating lots of empty ArrayList
instances, as Collections.emptyList()
is a static instance (only one exists) and is not modifiable.
For java 6 (or openjdk 7), not specifying an initial size gives you a list within initial size set to 10. So depending on many factors of your usage of the list, it could be very slightly more memory and/or performance efficient to initialize the list with size 0
.
For java 7, specifying an initial size 0
is functionally equivalent to not specifying an initial size.
However it is actually less efficient, since the call to the constructor with argument 0
incurs a call to new Object[0]
, whereas if you specify the no-args constructor, the initial elementData
for your list is set to a statically defined constant named EMPTY_ELEMENTDATA
.
Relevant code from ArrayList
source:
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
In other words the use of new ArrayList<Integer>(0);
seems superfluous, there are no benefits to doing so, and I would use new ArrayList<Integer>();
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With