Long time ago I watched a video lecture from the Princeton Coursera MOOC: Introduction to algorithms, which can be found here. It explains the cost of resizing an ArrayList
like structure while adding or removing the elements from it. It turns out that if we want to supply resizing to our data structure we will go from O(n)
to amortized O(n)
for add
and remove
operations.
I have been using Java ArrayList
for a couple of years. I've been always sure that they grow and shrink automatically. Only recently, to my great surprise, I was proven wrong in this post. Java ArrayList
s do not shrink (even though, of course they do grow) automatically.
Here are my questions:
In my opinion providing shrinking in ArrayList
s does not make any harm as the performance is already amortized O(n)
. Why did Java creators did not include this feature into the design?
I know that other data structures like HashMap
s also do not shrink automatically. Is there any other data structure in Java which is build on top of arrays that supports automatic shrinking?
What are the tendencies in other languages? How does automatic shrinking look like in case of lists, dictionaries, maps, sets in Python/C# etc. If they go in the opposite direction to what Java does, then my question is: why?
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.
ArrayList supports dynamic arrays that can grow as needed. Standard Java arrays are of a fixed length. After arrays are created, they cannot grow or shrink, which means that you must know in advance how many elements an array will hold. Array lists are created with an initial size.
The size of an ArrayList cannot be changed after the ArrayList is initialized.
The comments already cover most of what you are asking. Here some thoughts on your questions:
When creating a structure like the ArrayList
in Java, the developers make certain decisions regarding runtime / performance. They obviously decided to exclude shrinking from the “normal” operations to avoid the additional runtime, which is needed.
The question is why you would want to shrink automatically. The ArrayList
does not grow that much (the factor is about 1.5; newCapacity = oldCapacity + (oldCapacity >> 1)
, to be exact). Maybe you also insert in the middle and not just append at the end. Then a LinkedList
(which is not based on an array -> no shrinking needed) might be better. It really depends on your use case. If you think you really need everything an ArrayList
does, but it has to shrink when removing elements (I doubt you really need this), just extend ArrayList
and override the methods. But be careful! If you shrink at every removal, you are back at O(n)
.
The C# List
and the C++ vector
behave the same concerning shrinking a list at removal of elements. But the factors of automatic growing vary. Even some Java-implementations use different factors.
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