Java ArrayList removing elements recover wasted space? [duplicate] - java

This question already has answers here:
Does the capacity of ArrayList decrease when we remove elements?
(7 answers)
Closed 3 years ago.
If you have an Array List that has been extended (the array has grown) to contain many elements and these elements are then removed, does the actual array size change to save memory?
In more details, when removing an element from a large Array List, is the reserved memory for the array empty part of the array recovered? It would seem logic that since we expanded the array we might need to use this space and so it will not be touched.
However if we have a really large array list and we only use the first 10 or so elements, will the compiler (or on run time) realize that all the extra space is being wasted and recover it? (Will the actual array size be decreased? (Copying the elements into a smaller array?))

You can call trimToSize() in order to replace the backing array of the ArrayList with a smaller array that matches the size of the list.
void java.util.ArrayList.trimToSize()
Trims the capacity of this ArrayList instance to be the list's current size. An application can use this operation to minimize the storage of an ArrayList instance.

Related

Why is an ArrayList faster to create and add 10 million elements to than a LinkedList? [duplicate]

This question already has answers here:
Performance differences between ArrayList and LinkedList [duplicate]
(11 answers)
When to use LinkedList over ArrayList in Java?
(33 answers)
Closed 1 year ago.
This post was edited and submitted for review 4 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Yesterday I ran a benchmark in Java 17 where I repeatedly created a new Arraylist and Linkedlist and added 10.000.000 Elements to it.
By the nature of a LinkedList adding elements (creating a LinkedObject an putting it at the end) should be much faster than adding to an ArrayList. (Copying whole array in anotherone that is slightly larger.)
Are native functions like arraycopy() really that much faster? The only thing the LinkedList was better at was merging two LinkedLists together.
Most of the time, adding to an ArrayList won't allocate a new array, since the implementation increases the size of the backing array by 50% when it needs to grow.
This may sound wasteful from a memory perspective, but even a worst-case scenario for a growing ArrayList uses less memory than LinkedList - each entry in a linked list costs an object header + 3 references (prev/value/next), whereas a worst-case growing ArrayList has only 1.5 references per entry (i.e., the array cells used, plus 50% which are as-yet unused).
Anywho, according to my calculations, this means that adding 10 million entries to a default-initiated ArrayList will result in some 35 array-copying actions, which isn't very much. (And yes, System.arraycopy is fast.)
Finally, if you give your array an initial capacity of 10_000_000, there will be zero array copies made. You can try that to see how much the copying really costs.

How are elements allocated in ArrayList vs Array? [duplicate]

This question already has answers here:
Why start an ArrayList with an initial capacity?
(11 answers)
Closed 2 years ago.
According to a book I was reading
There is an important distinction between the capacity of an array list
and the size of an array. If you allocate an array with 100 entries,
then the array has 100 slots, ready for use. An array list with a
capacity of 100 elements has the potential of holding 100 elements
(and, in fact, more than 100, at the cost of additional reallocations)—
but at the beginning, even after its initial construction, an array list
holds no elements at all.
However, we can also create an ArrayList without any capacity defined.
How will an ArrayList without any capacity defined and an ArrayList with capacity allocate its elements and when we should use one over the other?
The only thing striking my mind is, why would we have capacity if in both ways (ArrayList with capacity and ArrayList with no capacity), the values will be treated same way, so the only possible reason coming in my mind is that they both hold values differently.
The reason for providing an initial allocation is to pre-allocate the memory representation required to hold that many items, otherwise dynamic allocation is necessary for all item added. Note, dynamic allocation becomes necessary once the array contains the number of pre-allocated items.

How can I resize array in java? [duplicate]

This question already has answers here:
Resize an Array while keeping current elements in Java?
(12 answers)
Closed 3 months ago.
As the title, how can I resize array in java, without importing any library, including ArrayList, Arrays.copyOf ...etc.
Also, I have to resize again and again in my program, with the unknown input data.( i.e. I have a small array, but when the data increasing, how can I resize it?)
Unfortunately, you cant resize an array in java.
Some things you could do are:
When new data is taken in, make a new array and copy the old array + the new data.
Use an ArrayList which makes the array bigger as you add data to it.
Use java.util.Arrays.copyOf(...). This returns a bigger array with the contents of the previous array.
Java does not have a "resize" option for allocated storage. You must allocate new storage of the required size and copy the data from the old storage to the new.
You can use System.arraycopy() to copy the data. The ArrayList and Vector classes automatically perform these reallocate and copy operations, so if you don't use them, you are reinventing the wheel.
java.lang.System is, of course, automatically imported into every java program, so, as required, you don't need import java.lang.System; to implement this.
a array is by definition fixed in size, I know many modern languages let you assign the length and change the length dynamically
but I think what you are looking for is a Vector
https://docs.oracle.com/javase/7/docs/api/java/util/Vector.html
it allows O(1) access (like the array) while beeing dynamic in length
You can not increase the size of an array once it is declared. So you have to use Collection framework in java, may be ArrayList or LinkedList.
That is what is the difference between Array and ArrayList. In ArrayList you can add element dynamically,no need to increase it's size.
you could use forEach to copy the values to the enlarged new array
IntStream.range( 0, oldArray.length ).forEach( i -> newArray[i] = oldArray[i] );

Performance - volume of data - ArrayList<String>, List<Object> vs LinkedList<String>, LinkedList<Object> [duplicate]

This question already has answers here:
When to use LinkedList over ArrayList in Java?
(33 answers)
Closed 7 years ago.
In my java app deployed on tomcat, about 500K items (can go even upwards) are
added to ArrayList.
Then, these list(s) are iterated to check some conditions.
Que- For this scenario, would using LinkedList gain performance?
Any pointers from practical experience for volume of data exceeding 200K items~ 1 million items.
Mostly list of strings and objects having multiple properties mostly string
(Basically get data from DB, convert it to Java objects and send it over via HTTP)
If size of data is expected to stay within 100K or less, would there be a difference
See this question:
When to use LinkedList over ArrayList?
LinkedList allows for constant-time insertions or removals using
iterators, but only sequential access of elements. In other words, you
can walk the list forwards or backwards, but finding a position in the
list takes time proportional to the size of the list.
ArrayList, on the other hand, allow fast random read access, so you
can grab any element in constant time. But adding or removing from
anywhere but the end requires shifting all the latter elements over,
either to make an opening or fill the gap. Also, if you add more
elements than the capacity of the underlying array, a new array (1.5
times the size) is allocated, and the old array is copied to the new
one, so adding to an ArrayList is O(n) in the worst case but constant
on average.

adding to the middle of an empty ArrayList?

if I create a new arraylist of size 5...
Player P;
ArrayList<Player> orderedPlayers = new ArrayList<Player>(5);
and then I try to add to the middle of that arraylist...
orderedPlayers.add(2, P);
I get an indexoutofbounds... I also get indexoutofbounds if I use set instead of add...
orderedPlayers.set(2, P);
in fact the only way I can add P to the arraylist is if I use the 0 index...
orderedPlayers.add(0, P);
and also for some strange reason when I do that my debugger in eclipse sees that element added to the 4th index of orderedPlayers instead of the 0th... is ArrayList buggy or am I completely missing something? how would I add to the middle of a null ArrayList?
The 5 is the initial capacity, not the actual size. You can't add to the middle of an empty array list.
Here is probably what you want to do in order to initialize orderedPlayers:
ArrayList<Player> orderedPlayers =
new ArrayList<Player>(Collections.nCopies( 5, null ));
Then you have a list with 5 null elements, at this point you can insert in the middle of it.
When you create an ArrayList with a number in parameter, this number will be used to set the initial capacity. That way the List won't need to create a new array for "every" call to add(). If you can tell that your List will contain 100 elements, you can use new ArrayList(100). That doesn't mean that the 100 elements exists or are accessible.
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost.
An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.
ArrayLists are dynamic structures... if you want to be able to add stuff at specific locations, you might have to use an array instead.
you may initialize your array list by NULL objects in a loop.
or even if the size is fixed. then use Array instead of List.
You seem to be under the mistaken impression that when you write new ArrayList<Player>(5), you're getting something similar to a 5-element array. You aren't. You're getting an empty list that happens to be backed by an internal array that can initially hold up to 5 elements. The list itself, however, has no elements at all.
Lists are dynamic and grow and shrink as elements are added to them and removed from them. You start out with 0 elements. If you then add 5 players, the list will have 5 elements. If you just use the normal add(T) method with no index, you'll end up with the elements in the order they were added.
By constructing an ArrayList with an initial capacity ArrayList(int initialCapacity), you are indicating roughly how large the list can get before Java will increase its size.
You are not allocating slots, as in an array. The ArrayList's size is based on the number of elements in the list, and you cannot insert or set a value to an index greater than its size.

Categories

Resources