Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of creating an ArrayList with initial capacity of 0?

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?

like image 734
Mauren Avatar asked Feb 05 '15 13:02

Mauren


People also ask

Can an ArrayList have a size of 0?

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.

What is the use of initial capacity in ArrayList?

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);

Does ArrayList size start at 0 or 1?

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.

What is the initial default capacity of an ArrayList?

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.


2 Answers

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.

like image 200
Craig Otis Avatar answered Oct 07 '22 19:10

Craig Otis


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.

like image 8
vikingsteve Avatar answered Oct 07 '22 19:10

vikingsteve