java Arraylist remove elements - java

Suppose there are 10 elements in ArrayList and if i have deleted 2 elements from the middle , so the arraylist will contain 8 elements , but will the capacity be 10 or reduced to 8 at that time.

The API states :
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.
and you can always test this empirically in your debugger. After removing two elements, look at the array that backs the ArrayList, and see what it's size is. Most likely, it's 10.

The behaviour depends on the implementation of the ArrayList. You can't rely on this kind of implementation details. The only thing you must consider is that the capacity is always greater or equal to the number of elements in your list. If you need the capacity to be exactly the number of elements (because you may want to reduce memory usage), you will have to ask it explicitly with the function trimToSize().

I think it may change because suppose we create new array list by default JVM allocate say 10 continuous locations in memory .if you put 8 or 2 or zero it will be same .
But is you put 15 element then it will increase it to say 20 memory locations .But if you below 10 again it should release that memory and reduce to 10 default size .
This is dynamic allocation .For 1000 element list if you are removing the element and reduce to 2 then it is logical that it must release that memory .It should depend on number of elements removed.

Related

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 to store sentences in a temporary array in Java?

Currently, I am scraping out a chunk of data (paragraphs/strings) from a text file and writing it out to a new file. However, I am planning on adding some conditionals later and thus want to be able to take out this chunk of data and only store it in a temporary array, then write out to a file if the conditionals are met. However, I am not sure how to write this out to an array without knowing the size of the array beforehand.
Does anyone have any ideas?
Don't use an array. Use a collection of type String that can grow dynamically such as an ArrayList for example. Here are some quick code samples: Sample 1, Sample 2
Some notes on an ArrayList's memory management from the Java docs:
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.
Notice that even the docs do not specify exactly how things are managed internally.
In Java, an ArrayList (or any other type of Java collection) can take care of all the memory management for you:
ArrayList<String> strings = new ArrayList<String>();
If you want to add a string:
strings.add("New String");
If you want to get a String at a certain index (in this example, index 1):
strings.get(1);
There are a lot more methods in the ArrayList class as well.
You do need a collection that grows dynamically. ArrayList is the first that comes to mind; internally it is very similar to a regular array, so it offers fast random access, if you need it. LinkedList may be better suited if you don't have an estimate about the number of elements that you will eventually need, provided that you will only need sequential access to its elements (random access is available, but it will not be fast).

How to define the concept of capacity in ArrayLists?

I understand that capacity is the number of elements or available spaces in an ArrayList that may or may not hold a value referencing an object. I am trying to understand more about the concept of capacity.
So I have three questions:
1) What are some good ways to define what capacity represents from a memory standpoint?
...the (contiguous?) memory allocated to the ArrayList?
...the ArrayLists’s memory footprint on the (heap?)?
2) Then if the above is true, changing capacity requires some manner of memory management overhead?
3) Anyone have an example where #2 was or could be a performance concern? Aside from maybe a large number of large ArrayLists having their capacities continually adjusted?
The class is called ArrayList because it's based on an array. The capacity is the size of the array, which requires a block of contiguous heap memory. However, note that the array itself contains only references to the elements, which are separate objects on the heap.
Increasing the capacity requires allocating a new, larger array and copying all the references from the old array to the new one, after which the old one becomes eligible for garbage collection.
You've cited the main case where performance could be a concern. In practice, I've never seen it actually become a problem, since the element objects usually take up much more memory (and possibly CPU time) than the list.
ArrayList is implemented like this:
class ArrayList {
private Object[] elements;
}
the capacity is the size of that array.
Now, if your capacity is 10, and you're adding 11-th element, ArrayList will do this:
Object[] newElements = new Object[capacity * 1.5];
System.arraycopy(this.elements, newElements);
this.elements = newElements;
So if you start off with a small capacity, ArrayList will end up creating a bunch of arrays and copying stuff around for you as you keep adding elements, which isn't good.
On the other hand, if you specify a capacity of 1,000,000 and add only 3 elements to ArrayList, that also is kinda bad.
Rule of thumb: if you know the capacity, specify it. If you aren't sure but know the upper bound, specify that. If you just aren't sure, use the defaults.
Capacity is as you described it -- the contiguous memory allocated to an ArrayList for storage of values. ArrayList stores all values in an array, and automatically resizes the array for you. This incurs memory management overhead when resizing.
If I remember correctly, Java increases the size of an ArrayList's backing array from size N to size 2N + 2 when you try to add one more element than the capacity can take. I do not know what size it increases to when you use the insert method (or similar) to insert at a specific position beyond the end of the capacity, or even whether it allows this.
Here is an example to help you think about how it works. Picture each space between the |s as a cell in the backing array:
| | |
size = 0 (contains no elements), capacity = 2 (can contain 2 elements).
|1| |
size = 1 (contains 1 element), capacity = 2 (can contain 2 elements).
|1|2|
size = 2, capacity = 2. Adding another element:
|1|2|3| | | |
size increased by 1, capacity increased to 6 (2 * 2 + 2). This can be expensive with large arrays, as allocating a large contiguous memory region can require a bit of work (as opposed to a LinkedList, which allocates many small pieces of memory) because the JVM needs to search for an appropriate location, and may need to ask the OS for more memory. It is also expensive to copy a large number of values from one place to another, which would be done once such a region was found.
My rule of thumb is this: If you know the capacity you will require, use an ArrayList because there will only be one allocation and access is very fast. If you do not know your required capacity, use a LinkedList because adding a new value always takes the same amount of work, and there is no copying involved.
1) What are some good ways to define what capacity represents from a memory standpoint?
...the (contiguous?) memory allocated to the ArrayList?
Yes, an ArrayList is backed up by an array, to that represents the internal array size.
...the ArrayLists’s memory footprint on the (heap?)?
Yes, the larget the array capacity, the more footprint used by the arraylist.
2) Then if the above is true, changing capacity requires some manner of memory management overhead?
It is. When the list grows large enough, a larger array is allocated and the contents copied. The previous array maybe discarded and marked for garbage collection.
3) Anyone have an example where #2 was or could be a performance concern? Aside from maybe a large number of large ArrayLists having their capacities continually adjusted?
Yes, if you create the ArrayList with initial capacity of 1 ( for instance ) and your list grows way beyond that. If you know upfront the number of elements to store, you better request an initial capacity of that size.
However I think this should be low in your list of priorities, while array copy may happen very often, it is optimized since the early stages of Java, and should not be a concern. Better would be to choose a right algorithm, I think. Remember: Premature optimization is the root of all evil
See also: When to use LinkedList over ArrayList

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.

Does the List in .NET work the same way as arraylist in Java?

When I learned Java, I was told that the arraylist works this way:
It creates an array with room for 10 elements.
When the 11th element is added, it is created a new list with room for 20 elements, and the 10 elements are copied into the new array. This will repeat as until there are no more elements to add, or to a maximum size.
Is the List in .NET constructed the same way?
You can easily test this by querying a List's Capacity:
var a = new List<string>();
Console.WriteLine(a.Capacity); // Writes 0
a.Add("abc");
Console.WriteLine(a.Capacity); // Writes 4
a.Add("abc");
a.Add("abc");
a.Add("abc");
a.Add("abc");
Console.WriteLine(a.Capacity); // Writes 8
So it doesn't allocate any room at all upon instantiation, but upon first added item. From 8 it grows to 16, 32, etc...
The generic List type doubles its internal array length every time the current array is filled up.
MSDN Link
The details are a bit different (in terms of the default number of elements and how it expands), but essentially it is the same.
I believe that's how it works, yes. I can't find any documentation at the moment that tells you the exact algorithm they use, but there is definitely the concept of Capacity (size of the "internal" array) and Count (the actual number of elements you've added).

Categories

Resources