If i need to initialize a static final Collection - java

I have one collection defined this way, without a specified size -
private final static Collection<String> mycollection = new ArrayList<String>();
static {
mycollection.add("mystr");
}
There is also a constructor that takes a size, e.g.
private final static Collection<String> mycollection = new ArrayList<String>(1);
static {
mycollection.add("mystr");
}
Since the Collection is final, should I be constructing it so that it is a specific size?

Setting the initial size of an ArrayList, reduces the number of times the re-allocation of internal memory has to occur. If you create an ArrayList without setting capacity within constructor it will be created with a default value, which I guess is 10. ArrayList is a dynamically re sizing data structure, implemented as an array with an initial (default) fixed size. If you know your upper bound of items, then creating the array with initial length is better I suppose.
As per the documentation of ArrayList() constructor :
Constructs an empty list with an initial capacity of ten.
Whereas , ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.
Since the Collection is final, should I be constructing it so that it is a specific size?
The reference variable is final , it can only point to one object , in this case the ArrayList . This doesn't imply that the contents or properties of ArrayList itself cannot be changed . Refer JLS 4.12.4
Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.

As the official JavaDoc says:
public ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.
public ArrayList()
Constructs an empty list with an initial capacity of ten.
So if you're not planning to add more elements, the first approach requires less memory. If you're going to add more elements to the collection, however, the second approach does not require re-allocating a new backing array as soon.

By detault, ArrayList creates and array of 10 elements in it's internal data structure if you do not pass any argument in it.
However, if you paas initialCapacity argument to it you are assigning an initial value to it, which may increase performance at time when you know in advance what will be the size of ArrayList.
public ArrayList(int initialCapacity)
So, in your case if there is only one element it does not makes any difference, but it the list is going to increase more, lowering the initial capacity will make it to recreate the array again.

The second way will save you a bit memory (the default initial capacity is equal to ten). Assuming you won't alter the list's contents (the underlying array will grow while you add new elements to it).
Notice that the collection isn't immutable (!), only the reference is final. For an immutable list, use Collections.unmodifiableList or Collections.unmodifiableCollection methods like this:
private final static Collection<String> mycollection;
static {
List<String> tempList = new ArrayList<String>(1);
tempList.add("mystr");
mycollection = Collections.unmodifiableCollection(tempList);
}

The former uses empty ArrayList constructor with an initial default capacity of 10 (refer to the previous link), while the latter uses ArrayList(int) constructor and you will set the initial capacity.
Do we have any memory or performance impact if i initialize.
If saving at least 9 bytes for initial array configuration when having 256 MBs to use, then I would say no.
If you're worried about the initial capacity of the internal array used by the ArrayList, here are two excellent Q/As on the subject:
ArrayList vs LinkedList from memory allocation perspective
Most memory efficient way to grow an array in Java?

Related

What is the benefit of setting the capacity of an ArrayList explicitly [duplicate]

This question already has answers here:
Why start an ArrayList with an initial capacity?
(11 answers)
Closed 9 months ago.
The community reviewed whether to reopen this question 9 months ago and left it closed:
Original close reason(s) were not resolved
In java ArrayList we have a constructor -
ArrayList(int capacity)
and two methods -
void ensureCapacity(int minCapacity)
void trimToSize()
Consider a code-sample:
ArrayList<String> arrayList3 = new ArrayList<>(5);
System.out.println(arrayList3.size());
arrayList3.add("Zebra");
arrayList3.add("Giraffe");
arrayList3.add("Bison");
System.out.println(arrayList3);
System.out.println(arrayList3.size());
arrayList3.add("Rhino");
arrayList3.add("Hippo");
arrayList3.add("Elephant");
arrayList3.add("Antelope");
System.out.println(arrayList3);
System.out.println(arrayList3.size());
Output:
0
[Zebra, Giraffe, Bison]
3
[Zebra, Giraffe, Bison, Rhino, Hippo, Elephant, Antelope]
7
Here, I fail to see how setting an initial capacity affects the execution of the program. ArrayList is a flexible list that changes size as per demand. So what is the significance of setting the capacity explicitly?
And in the case if I want to set the capacity explicitly, is there any method to view the current capacity? Since int size() clearly is not applicable here.
ArrayList as an implementation of a Dynamic array data structure.
It resizes when its underlying array gets full (i.e. the current list index exceeds the last valid index of the underlying array).
When it happens, method add() (or addAll) internally will invoke the method grow(). Which will double the capacity. I.e. it will create a new array with the length two times bigger than the previous length plus a number of new elements that don't fit into the current size.
The growth has a cost of O(n) because all previously added elements need to be copied into the new array.
Reminder: when resizing isn't required, a new element will be added in constant time O(1).
No-argument constructor creates an ArrayList with capacity of 10.
If you expect that a newly created ArrayList would eventually contain let's say 50,000 elements, it makes sense to use an overloaded constructor to provide the initial capacity of 50,000 in order to improve performance by avoiding unnecessary resizing.
Also, for that you can use method ensureCapacity() which accessible in the ArrayList class (not in the List interface, because the notion of capacity isn't applicable to LinkedList which isn't backed by an array).
is there any method to view the current capacity
No, there isn't. That's called encapsulation. ArrayList, StringBuilder, HashMap, etc. are backed by a plain array, but they will not allow interacting with their underlying array directly.
But if you have a case when array initially increases size and then a lot of elements are being removed, and you want to release unoccupied heap space, you can use method 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.
But it has to be used with caution, because it can lead to cyclic growth and trimming, which will cause performance degradation.
Note that there's no need to worry about the amount of unoccupied space if the list is moderate in size, or if you are not expecting let's say 80% of the data to be removed in one go. I.e. even if the list is huge but 50% of its elements gets removed, and you apply trimToSize() on it, it'll restore its previous capacity with the next added element - that's the scenario of continuously growing and shrinking list which will perform badly.
As a possible option, if you heave a case when most of the data can be removed from a list, instead of using trimToSize() you can filter out the elements that have to be preserved, place them into a new list and dereference the previous one.

How does Java implement "growable array" internally? [duplicate]

What data structure does an ArrayList use internally?
Internally an ArrayList uses an Object[].
As you add items to an ArrayList, the list checks to see if the backing array has room left. If there is room, the new item is just added at the next empty space. If there is not room, a new, larger, array is created, and the old array is copied into the new one.
Now, there is more room left, and the new element is added in the next empty space.
Since people really like the source code:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;
Straight out of the JDK.
It uses an Object[], and makes a bigger array when the array gets full.
You can read the source code here.
ArrayList uses an Array of Object to store the data internally.
When you initialize an ArrayList, an array of size 10 (default capacity) is created and an element added to the ArrayList is actually added to this array. 10 is the default size and it can be passed as a parameter while initializing the ArrayList.
When adding a new element, if the array is full, then a new array of 50% more the initial size is created and the last array is copied to this new array so that now there are empty spaces for the new element to be added.
Since the underlying data-structure used is an array, it is fairly easy to add a new element to the ArrayList as it is added to the end of the list. When an element is to be added anywhere else, say the beginning, then all the elements shall have to move one position to the right to create an empty space at the beginning for the new element to be added. This process is time-consuming (linear-time). But the Advantage of ArrayList is that retrieving an element at any position is very fast (constant-time), as underlying it is simply using an array of objects.
ArrayList has the basic data structure:
private transient Object[] elementData;
When we actually create an ArrayList the following piece of code is executed:
this.elementData = new Object[initial capacity];
ArrayList can be created in the two ways mentioned below:
List list = new ArrayList();
The default constructor is invoked and will internally create an array of Object with default size 10.
List list = new ArrayList(5);
When we create an ArrayList in this way, constructor with an integer argument is invoked and
create an array of Object with default size 5.
Inside the add method there is check whether the current size of filled elements is greater/equal to the maximum size of the
ArrayList then it will create new ArrayList with the size new arraylist = (current arraylist*3/2)+1 and copy the data from old to
new array list.
It uses an array, and a couple of integers to indicate the first value - last value index
private transient int firstIndex;
private transient int lastIndex;
private transient E[] array;
Here's an example implementation.
Typically, structures like ArrayLists are implemented by a good old fashioned array defined within the class and not directly accessible outside the class.
A certain amount of space is initially allocated for the list, and when you add an element that exceeds the size of the array, the array will be reinitialized with a new capacity (which is typically some multiple of the current size, so the framework isn't constantly re-allocating arrays with each new entry added).
The Java platform source code is freely available. Here's an extract:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient E[] elementData;
.
.
.
}
ArrayLists use arrays to hold the data. Once the number of elements exceeds the allocated array it copies the data to another array, probably double the size.
A (minor) performance hit is taken when copying the array, it's therefore possible to set the size of the internal array in the constructor of the array list.
Furthermore it implements java.util.Collection and and java.util.list, and it's is therefore possible to get the element at a specified index, and iterable (just like an array).
It uses an Object[]. When the array is full it creates a new array which is 50% bigger in size and copies current elements to new array. It happens automatically.
as i understand is that
ArrayList class implements List interface and
(as interface only extends other interface)
List interface extends Collection interface.
while talking about arraylist when we initialize in memory it reserve by default space 10 > and create array of Integer which you normally use. when this this array is full then the another array of interger is created which is greater then default size.
List<Integer> list = new ArrayList<>();
now in memory as => Integer[] list = new Integer[10];
now suppose that you enter 1,2,3,4,5,6,7,8,9,10 array is full now and what happen when you enter 11 in the memory another array of Integer is created which is greater then by default and all element in old array is copied in new array. Internally arraylist user Object[] array.
thats how arrayList work
Basic Data Structure which is used in an ArrayList is –
private transient Object[] elementData;
So, going by declaration it’s an array of Object.
When we actually create an arrayList following piece of code is executed –
this.elementData=new Object[initial capacity];
When we create an ArrayList, default constructor is invoked and will internally create an array of Object with default size, which is 10. Now, As we all know that unlike normal arrays, the size of the ArrayList grows dynamically. But how its size grows internally?
So what happens internally is a new Array is created with size 1.5 x currentSize and the data from old Array is copied into this new Array. Every time when it reaches ArrayList at maximum capacity then copy and destroy previous array make new array with new capacity (1.5 x old capacity).
For more details your can read my blog here.

Instantiating an ArrayList of ArrayLists

I want to instantiate an ArrayList of ArrayLists (of a generic type). I have this code:
private ArrayList<ArrayList<GameObject>> toDoFlags;
toDoFlags = new ArrayList<ArrayList<GameObject>>(2);
Am I doing this right? It compiles, but when I look at the ArrayList, it has a size of 0.
You're doing it right. The reason it has zero length is because you haven't added anything to it yet.
The "2" you pass is the initial capacity of the array that backs the ArrayList. But the size() method of the ArrayList doesn't return the initial capacity of its backing array... it returns the number of actual elements in the list.
Customarily, you shouldn't be using the initialCapacity parameter. It's a performance optimization when you have large ArrayLists. By allocating a lot of space explicitly, you save the time it would take to re-allocate as you add more and more items to the list. But in this case you probably don't have an extremely large list.
Also, instead of using an ArrayList of ArrayLists, you should consider writing a class to store your data.
ArrayLists expand as you add to them. The integer capacity argument just sets the initial size of the backing array. Setting the capacity to two doesn't mean that there are two elements in the ArrayList, but rather that two elements can be added to the ArrayList before it has to declare a larger internal array.

How does ArrayList work?

What data structure does an ArrayList use internally?
Internally an ArrayList uses an Object[].
As you add items to an ArrayList, the list checks to see if the backing array has room left. If there is room, the new item is just added at the next empty space. If there is not room, a new, larger, array is created, and the old array is copied into the new one.
Now, there is more room left, and the new element is added in the next empty space.
Since people really like the source code:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;
Straight out of the JDK.
It uses an Object[], and makes a bigger array when the array gets full.
You can read the source code here.
ArrayList uses an Array of Object to store the data internally.
When you initialize an ArrayList, an array of size 10 (default capacity) is created and an element added to the ArrayList is actually added to this array. 10 is the default size and it can be passed as a parameter while initializing the ArrayList.
When adding a new element, if the array is full, then a new array of 50% more the initial size is created and the last array is copied to this new array so that now there are empty spaces for the new element to be added.
Since the underlying data-structure used is an array, it is fairly easy to add a new element to the ArrayList as it is added to the end of the list. When an element is to be added anywhere else, say the beginning, then all the elements shall have to move one position to the right to create an empty space at the beginning for the new element to be added. This process is time-consuming (linear-time). But the Advantage of ArrayList is that retrieving an element at any position is very fast (constant-time), as underlying it is simply using an array of objects.
ArrayList has the basic data structure:
private transient Object[] elementData;
When we actually create an ArrayList the following piece of code is executed:
this.elementData = new Object[initial capacity];
ArrayList can be created in the two ways mentioned below:
List list = new ArrayList();
The default constructor is invoked and will internally create an array of Object with default size 10.
List list = new ArrayList(5);
When we create an ArrayList in this way, constructor with an integer argument is invoked and
create an array of Object with default size 5.
Inside the add method there is check whether the current size of filled elements is greater/equal to the maximum size of the
ArrayList then it will create new ArrayList with the size new arraylist = (current arraylist*3/2)+1 and copy the data from old to
new array list.
It uses an array, and a couple of integers to indicate the first value - last value index
private transient int firstIndex;
private transient int lastIndex;
private transient E[] array;
Here's an example implementation.
Typically, structures like ArrayLists are implemented by a good old fashioned array defined within the class and not directly accessible outside the class.
A certain amount of space is initially allocated for the list, and when you add an element that exceeds the size of the array, the array will be reinitialized with a new capacity (which is typically some multiple of the current size, so the framework isn't constantly re-allocating arrays with each new entry added).
The Java platform source code is freely available. Here's an extract:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient E[] elementData;
.
.
.
}
ArrayLists use arrays to hold the data. Once the number of elements exceeds the allocated array it copies the data to another array, probably double the size.
A (minor) performance hit is taken when copying the array, it's therefore possible to set the size of the internal array in the constructor of the array list.
Furthermore it implements java.util.Collection and and java.util.list, and it's is therefore possible to get the element at a specified index, and iterable (just like an array).
It uses an Object[]. When the array is full it creates a new array which is 50% bigger in size and copies current elements to new array. It happens automatically.
as i understand is that
ArrayList class implements List interface and
(as interface only extends other interface)
List interface extends Collection interface.
while talking about arraylist when we initialize in memory it reserve by default space 10 > and create array of Integer which you normally use. when this this array is full then the another array of interger is created which is greater then default size.
List<Integer> list = new ArrayList<>();
now in memory as => Integer[] list = new Integer[10];
now suppose that you enter 1,2,3,4,5,6,7,8,9,10 array is full now and what happen when you enter 11 in the memory another array of Integer is created which is greater then by default and all element in old array is copied in new array. Internally arraylist user Object[] array.
thats how arrayList work
Basic Data Structure which is used in an ArrayList is –
private transient Object[] elementData;
So, going by declaration it’s an array of Object.
When we actually create an arrayList following piece of code is executed –
this.elementData=new Object[initial capacity];
When we create an ArrayList, default constructor is invoked and will internally create an array of Object with default size, which is 10. Now, As we all know that unlike normal arrays, the size of the ArrayList grows dynamically. But how its size grows internally?
So what happens internally is a new Array is created with size 1.5 x currentSize and the data from old Array is copied into this new Array. Every time when it reaches ArrayList at maximum capacity then copy and destroy previous array make new array with new capacity (1.5 x old capacity).
For more details your can read my blog here.

What is the exact difference between these two groups of statements?

Set<Type> union = new HashSet<Type>(s1);
And
Set<Type> union = new HashSet<Type>();
Set<Type> s1 = new HashSet<Type>();
union.addAll(s1);
The first will be more efficient because the second Set will be created with the correct amount of space in the backing data structure where in the second piece of code, the Set will have to resize to make room for the new elements.
As far as end results go, they are the same.
Assuming that Set s1 contains the same contents in the first and second examples, the end results should come out to be the same.
(However, the second example will not compile because a Set is an interface rather than a concrete class.)
One advantage of using the HashSet(Collection) constructor is that it will have an initial capacity that is enough to hold the Collection (in this case, the Set s1) that is passed into the constructor:
Constructs a new set containing the
elements in the specified collection.
The HashMap is created with default
load factor (0.75) and an initial
capacity sufficient to contain the
elements in the specified collection.
However, using the HashSet() constructor, the initial size is 16, so if the Set that was added via the Collection.addAll is larger than 16, there would have to be a resizing of the data structure:
Constructs a new, empty set; the
backing HashMap instance has default
initial capacity (16) and load factor
(0.75).
Therefore, using the HashSet(Collection) constructor to create the HashSet would probably be a better option in terms of performance and efficiency.
However, from the standpoint of readability of the code, the variable name union seems to imply that the newly created Set is an union of another Set, so probably the one using the addAll method would be more understandable code.
If the idea is just to make a new Set from an existing one, then the newly created Set should probably be named differently, such as newSet, copyOfS1 or something to that effect.
There is no difference. Both will create a new set that contains all of the elements in the set s1.
Of course, your second code sample won't even compile, since you can't directly instantiate the Set interface, but I'm assuming that you meant to say new HashSet instead of new Set.
There is a little difference, in that the new HashSet(s1) will make sure beforehand that all elements will fit, and no rehashing is needed.

Categories

Resources