CodingBison

As we know List is an ordered Collection, all the objects in the List can be accessed/manipulated using an integer index, which represents the position at which they are stored in the List. More details about List interface is available here.



Figure: List Interface and Class Hierarchy

One of the two classes that implements the interface List, is an ArrayList. The ArrayList class implements all the methods defined in the List interface and it also provides some extra methods that helps in manipulating the objects stored in the ArrayList.

Things To Remember
The initial default-size/capacity of an ArrayList is 10.

When an ArrayList is created, it is created with a certain size/capacity, and as more and more elements are added to an ArrayList, its size grows automatically. So, the application need not worry about the size. Having said that, this behavior comes at the cost of performance and here is the reason why. An ArrayList of size N, when gets full grown to a size of N + K, where K would be greater than N (Usually). When this happens, all the elements of the older ArrayList (size K) are copied into the new ArrayList (size N + K) and the old ArrayList is deleted after the new ArrayList is created. All these operations consume CPU time, which leads to performance degradation. So, it is always better to have an ArrayList of bigger capacity at the time of creation itself.

In fact, ArrayList class provides a constructor that takes "Capacity" as an argument. Using that constructor we can specify the initial capacity of an ArrayList. We will see more about ArrayList constructors in the next section.

ArrayList Class Constructors

ArrayList class provides 3 Constructors and, here is the table that lists them.


Table: Constructors provided by ArrayList Class
ConstructorDescription
ArrayList()Creates an empty ArrayList with a default size of 10.
ArrayList(int initialSize)Creates an empty ArrayList with a size equal to "initialSize".
ArrayList(Collection c)Creates an ArrayList with all the elements of the specified Collection "c".

Here is an Example program that demonstrates the usage of the above Constructors.

 import java.util.ArrayList;

 public class ArrayListClassDemo {
     public static void main(String[] args) {
 	/* If a collection object is declared this way, then there 
 	 * is no need for an explicit type casting, while adding an
 	 * object to this collection. In the Below example, notice 
 	 * the difference in the 2 statements.
 	 * alistObj1.add(1);  Vs  alistObj2.add(new Integer(10));
 	 */
 	ArrayList<Integer> alistObj1 = new ArrayList<Integer>();
 	alistObj1.add(1);
 	alistObj1.add(33);

 	// Creates an ArrayList with a default size of 10.
 	ArrayList alistObj2= new ArrayList();
 	alistObj2.addAll(alistObj1);
 	alistObj2.add(new Integer(10));
 	alistObj2.add(1, new Integer(12));

 	// Creates an ArrayList with a size of "25".
 	ArrayList alistObj3 = new ArrayList(25);
 	// Creates an ArrayList with all the elements of Collection alistObj2
 	ArrayList alistObj4 = new ArrayList(alistObj2);

 	// Prints the Entire List alistObj2
 	System.out.println(" Printing the list (alistObj2): " + alistObj2);
 	// Prints the Entire List alistObj4 
 	System.out.println(" Printing the list (alistObj4): " + alistObj4);
     }
 }

In the above example, alistObj1 are alistObj2 are created using the default constructor. The object alistObj3 is created using a constructor that takes the size as a parameter, alistObj3 is created with a size of 25. The fourth object alistObj4 is created using a constructor that takes Collection object as parameter. So, alistObj4 is created with all the elements of collection, alistObj3 in this case. The output of both the objects alistObj3 and alistObj4 should be identical.

Let us Compile/run the program, Here is the output:

  Printing the list (alistObj2): [1, 12, 33, 10]
  Printing the list (alistObj4): [1, 12, 33, 10]

ArrayList Class Methods

As we already know, ArrayList is one of the Classes that implements the List interface. So, ArrayList class implements all the methods that are defined in the List interface in-addition to its own methods. The below table has the list of the methods that are defined by an ArrayClass. You can imagine this table to be an extension of the table List Interface Methods List.


Table: Methods provided by ArrayList Class
MethodDescription
void ensureCapacity(int minCapacity)Increases the capacity of the ArrayList object that invokes this method
protected void removeRange(int fromIndex, int toIndex)Removes all the elements "in the specified range, inclusive fromIndex, excluding toIndex" from the ArrayList object that invokes this method.
protected void trimToSize()Trims the size of the ArrayList object that invokes this method. For example, an ArrayList of size N would be reduced to the size of K. Where K is the current size of the ArrayList

Here is an Example program, that demonstrates the usage of the methods provided by ArrayList.

 import java.util.ArrayList;
 public class ArrayListClassMethodsDemo {
     public static void main(String[] args) {
 	/* If a collection object is declared this way, then there 
 	 * is no need for an explicit type casting, while adding an
 	 * object to this collection. In the Below example, notice 
 	 * the difference in the 2 statements.
 	 * alistObj1.add(1);  Vs  alistObj2.add(new Integer(10));
 	 */
 	ArrayList<Integer> alistObj1 = new ArrayList<Integer>();
 	alistObj1.add(1);
 	alistObj1.add(33);
 	alistObj1.add(21);
 	alistObj1.add(38);
 	ArrayList alistObj2= new ArrayList();
 	alistObj2.addAll(alistObj1);
 	alistObj2.add(new Integer(10));
 	alistObj2.add(new Integer(12));

 	// Changes the Min capacity to 20 from the default value 10.
 	alistObj1.ensureCapacity(20);

 	// This will make the size of the List to the Current size which is 4.
 	alistObj1.trimToSize();
 	// Prints the Entire List, after adding 12 at index 1
 	System.out.println(" Printing the list: " + alistObj1);
 	System.out.println(" Print the sub-list " + alistObj1.subList(1, 3));
     }
 }

Let us Compile/run the program, Here is the output:

  Printing the list: [1, 33, 21, 38]
  Print the sub-list [33, 21]

Clone Operation on the ArrayList

Things To Remember
The same kind of behavior may not be seen, if the ArrayList elements were to be of type "Integer Class" or "String Class", because they are immutable. Immutable, means the values cannot be changed.

List interface provides an other important operation called "clone" , where one can get to make a shallow copy of the ArrayList. So, what does a shallow copy mean ? It means the elements of the List are not copied, it just just creates an instance of the ArrayList. A change made using one object, gets reflected to the other object.

If you are familiar with "C" programming, a shallow copying is like having two pointers to the same variable, where both pointers point to the address of a variable, changes made to the variable at that address will be seen by all the pointers pointing to that address.

The below example program, demonstrates the usage of the "clone" method. Notice that ArrayList object alistObj2 is a cloned copy of alistObj1, which has 2 elements movieObj1, movieObj12 of type Movie. The program tries to change the element movieObj1 using the cloned object alistObj2. So, the change made by the cloned object alistObj2, on the element "movieObj1" is reflected on to the original element "movieObj1" directly.

 import java.util.ArrayList;

 class Movie {
     String name;

     public String getName() {
 	return name;
     }
     public void setName(String name) {
 	this.name = name;
     }
 }

 public class ArrayListClassCloneMethodDemo {
     public static void main(String[] args) {
 	Movie movieObj1 = new Movie();
 	Movie movieObj2 = new Movie();

 	movieObj1.name = "Casino Royal";
 	movieObj2.name = "SkyFall";

 	ArrayList alistObj1 = new ArrayList();
 	alistObj1.add(movieObj1);
 	alistObj1.add(movieObj2);

 	ArrayList alistObj2 = new ArrayList();
 	alistObj2 = (ArrayList) alistObj1.clone();

 	System.out.println("Movie Object 1: " + movieObj1.getName());

 	Movie temoMovieObj = (Movie) alistObj2.get(0);
 	temoMovieObj.setName("Spectre");

 	System.out.println("Movie Object 1, cloned ArrayList "
 	    		   + "object changed name to: "
 	    		   + movieObj1.getName());

        movieObj1.setName("Casino Royal");
        System.out.println("Name changed back by the original Object," +
 			  " Get the name using Cloned Object: " + 
 	    		   temoMovieObj.getName());

        Movie temoMovieObj1 = (Movie) alistObj1.get(0);
        System.out.println("Doesn't matter how you access the object," +
 			  " Get the name using original Object: " + 
 			   temoMovieObj1.getName());
     }
 }

Let us Compile/run the program, Here is the output:

 Movie Object 1: Casino Royal
 Movie Object 1, cloned ArrayList object changed name to: Spectre
 Name changed back by the original Object, Get the name using Cloned Object: Casino Royal
 Doesn't matter how you access the object, Get the name using original Object: Casino Royal




comments powered by Disqus