Powered by Blogger.

When to use ensureCapacity method in java

>> Sunday, January 5, 2014

In java Colleciton framework ArrayList and Vector classes contains ensureCapacity(int minCapacity) method to reduce or manage the amount of incremental memory allocation.
When to use ensureCapacity method in java_javabynataraj
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.

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.
Syntax: void  ensureCapacity(int minCapacity)
Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.

First, let you know the initial capacity of an ArrayList while creating an ArrayList instance.
List al = new ArrayList();
Here we are creating instance of ArrayList al by calling ArrayList constructor.This Constructs an empty list with an initial capacity of 10.

Java Code in ArrayList Class:
/**
  * Constructs an empty list with an initial capacity of ten.
  */
 public ArrayList() {
 this(10);
 }
We can override the constructor with capacity to change the initialization capacity of an ArrayList: 
List al = new ArrayList(4);

Now the capacity of an ArrayList is 4. Here we are explicitly passing the capacity of an ArrayList.

Actually ArrayList don't have any specific method to find capacity, but The closest you can get to controlling the capacity is through the constructor ArrayList(int initialCapacity), and the two methods trimToSize() and ensureCapacity(int minCapacity). Vector is having capacity method to find capacity of it's.

Syntax: int capacity()
//Returns the current capacity of this vector.
Here we have to understand that, how the capacity is allocating to ArrayList. We will go through the code below explained by aioobe in detail. The below code is for only to understand. Dont use this in real-time , this may cause ugly reflection-hack.
package com.javabynataraj;
//http://javabynataraj.blogspot.com
import java.lang.reflect.Field;
import java.util.ArrayList;
public class Test {

    public static void main(String[] args) throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>(4);
        for (int i = 0; i < 7; i++) {
          list.add(i);
          System.out.format("Size: %2d, Capacity: %2d%n",
          list.size(), getCapacity(list));
        }
    }
    static int getCapacity(ArrayList<?> l) throws Exception {
      Field dataField = ArrayList.class.getDeclaredField("elementData");
      dataField.setAccessible(true);
      return ((Object[]) dataField.get(l)).length;
    }
}
Output:
Size:  1, Capacity:  4
Size:  2, Capacity:  4
Size:  3, Capacity:  4
Size:  4, Capacity:  4
Size:  5, Capacity:  7
Size:  6, Capacity:  7
Size:  7, Capacity:  7

Now increase the value in for loop condition above from 7 to 8.
        for (int i = 0; i < 8; i++) {
Then run agian.

The output could be
Size:  1, Capacity:  4
Size:  2, Capacity:  4
Size:  3, Capacity:  4
Size:  4, Capacity:  4
Size:  5, Capacity:  7
Size:  6, Capacity:  7
Size:  7, Capacity:  7
Size:  8, Capacity: 11


Here you can see the Capacity is increased from 7 to 11. This is based on ArrayList principle "an ArrayList Capacity can grow or shrink dynamically based on size or elements contains".

The capacity will grow based on the principle
int newCapacity = (oldCapacity * 3)/2 +1
i.e:    (4*3)/2 + 1 = 7
        (7*3)/2 + 1 = 11

Here the situation to enter ensureCapacity method. Here to insert 8 elements in an ArrayList it is enough with Capacity 8. But we have 3 more capacity. The amount of allocation is going to waste unnecessarily. So we can use ensureCapacity method to reduce the capacity of an ArrayList.
package com.javabynataraj;
//http://javabynataraj.blogspot.com
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class TestEnsureCapacity {

     public static void main(String[] args) throws Exception {
 ArrayList<Integer> list = new ArrayList<Integer>(4);
    for (int i = 0; i < 8; i++) {
      list.add(i);
      System.out.format("Size: %2d, Capacity: %2d%n",
      list.size(), getCapacity(list));
      //this will increase the capacity of the ArrayList to 8 elements
      list.ensureCapacity(8);
    }
 }
    static int getCapacity(ArrayList<?> l) throws Exception {
      Field dataField = ArrayList.class.getDeclaredField("elementData");
      dataField.setAccessible(true);
      return ((Object[]) dataField.get(l)).length;
 }
}
Output:
Size:  1, Capacity:  4
Size:  2, Capacity:  8
Size:  3, Capacity:  8
Size:  4, Capacity:  8
Size:  5, Capacity:  8
Size:  6, Capacity:  8
Size:  7, Capacity:  8
Size:  8, Capacity:  8

Here we can see the Capacity is fixed to 8 upto the ArrayList contains 8 elements. Here we are not allocating more capacity for unnecessary elements. This is where we use to reduce the amount of incremental reallocation using ensureCapacity method.

Reference Books:

Related Posts Plugin for WordPress, Blogger...
© javabynataraj.blogspot.com from 2009 - 2014. All rights reserved.