ArrayList Write Operations explored

Hello Friends,

We will discuss today on various operations which can be performed on an ArrayList

For easy understanding,I am dividing operations into two parts:

1) Write Operations
2) Read Operations

In this article,We will discuss only on Write operations.


1) Write Operations





a) How to add elements in the list

Adding elements one by one and one after other using add method

List<String> list = new ArrayList<String>();
list.add("a");

This will add element "a" at zeroth index.

list.add("c");

This will add element "b" at first index.

list.add("d");

This will add element "c" at second index.

So we conclude from this that ArrayList use zero basesd indexing just like arrays.Here we should remember that ArrayList is actually implemented using arrays only.To know more about how ArrayList works ,you can read ArrayList features every java developer must know.


I would discuss indexOf method later,but to check if the index is actually zero based,we can check as follow

System.out.println("List Size:"+list.size());
System.out.println("Index of a:"+list.indexOf("a"));
System.out.println("Index of b:"+list.indexOf("c"));
System.out.println("Index of c:"+list.indexOf("d"));

Output : 
Index of a:0
Index of c:1
Index of d:2

Adding element at specific index using add method

list.add(1,"b");

This will add element "b" at 1st position in the ArrayList.But if this is going to insert element "b" at 1st position then what is going to happen with element "c" which is already there at 1st position.

I think you guessed it right.....

So below are the sequence of events that will happen when element "b" is added at 1st position.

Element at position 2 ("d") is moved to position 3.
Element at position 1("c") is moved to position 2
Newly added element "b" is inserted into position 1.

So basically it shifts element at the current position and subsequent elements towards one position right and inserts new element at the specified index.

Now lets try to add all element starting from index zero using this method.

List<String> list = new ArrayList<String>();
System.out.println("List Size:"+list.size());
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");

for (String str : list){
   System.out.println(str);
}

Output :
List Size:0
a
b
c

So far so good.....Now lets start elements directly from index 1

List<String> list = new ArrayList<String>();
System.out.println("List Size:"+list.size());
list.add(1,"a");
list.add(2,"b");
list.add(3,"c");

for (String str : list){
   System.out.println(str);
}

Output :
List Size:0
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
 at java.util.ArrayList.add(ArrayList.java:367)
 at com.test.TestComment.main(TestComment.java:15)

So from above code we can see that when we instantiate ArrayList ,it is created with default capacity of 10 but initial size of zero and we can't start adding element in ArrayList from postion 1,we have to start with inserting element from position zero.

If we see source code for add(index,element) method,it says 

if (index > size || index < 0) 
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); 

Now when we are adding element directly from position 1,that time size of the ArrayList is still zero,so above condition will be true(1(index) > 0(size)),so IndexOutOfBoundException,but when we start adding elements from position zero,above condition will be false(0(index) > 0(size)),so no IndexOutOfBoundException.

So what if we want to have ArrayList with some intial size as non zero.We can do something like as below 

List<Integer> list = new ArrayList<Integer>(Arrays.asList(new Integer[15]));

This will create ArrayList with 
initial size of 15 and we can add elements like

list.add(1,1);

Adding elements of another collection at the end of existing list  using addAll method

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");

List<String>  newList = new ArrayList<String>();
newList.add(0,"d");
newList.add(1,"e");

list.addAll(newList);
for(String str : list){
  System.out.println(str);
}

Output :
a
b
c
d
e

Lets try to add a Set to list

List<String> list = new ArrayList<String>();
list.add(1,"a");
list.add(2,"b");
list.add(3,"c");

Set<String> set = new HashSet<String>();
set.add("d");
set.add("e");

list.addAll(set);

for(String str : list){
  System.out.println(str);
}

Output :
a
b
c
d
e

We need to note here that order in which elements of set will be displayed can be different from the order in which they are inserted as HashSet does not maintain the insertion order.Basically addAll method appends all the elements of  collection passed as parameter to it ,to the end of list ,in the order returned by the iterator of that collection.

Adding elements of another collection at the specified position in existing list  using addAll method

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");

List<String> anotherList = new ArrayList<String>();
anotherList.add("d");
anotherList.add("e");
list.addAll(2, anotherList);

for(String str : list){
   System.out.println(str);
}

output :
a
b
d
e
c


Adding element at specific position using Set method

List<String> list = new ArrayList<String>();

list .add ("a");
list.add("b");
list.add("c");
System.out.println("Before adding element by calling set method");
for(String str : list){
              System.out.println(str);
}

//Using Set method to add element in lits

list.set(1,"d");
System.out.println("After adding element at position 1 by calling set method");
for(String str : list){
              System.out.println(str);
}


Output : 
Before adding element by calling set method
a
b
c
After adding element at position 1 by calling set method
a
d
c


As you can see from above output,set method replaces the element at the specified location with the element that is passed to it.

Difference between add(index,element) and set(index,element) method

While add(index,element) adds element at specified position and moves existing element at that position and next elements by 1 position towards right,set method simply replaces element at the specified position with the element that is passed to set method.So use add method when you want to insert element in the existing list such that you don't want to overwrite any existing element,however use set method when you want to replace element at specified location with  new element.

You can add elements in the list from zeroth index as below using add method

list.add(0,"a");

but you can not add elements to list using set method like below

list.set(0,"a");

This will give you following exception 
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0

It makes sense that set method is implemented like this,as set method is for replacing an existing element in the list.In the above case we are trying to say that replace element at position zero with element "a" when there is actually no element at position zero,so it is throwing exception.

b) How to remove elements from ArrayList

Removing first occurrence of element from a list using remove method 

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
list.add(3,"a");

System.out.println("List before removal of elements");

for(String str : list){
   System.out.println(str);
}
list.remove("a");

System.out.println("List after removal of first occurrence of element a");

for(String str : list){
   System.out.println(str);
}

Output :
List before removal of elements
a
b
c
a
List after removal of element a
b
c
a

Removing all occurrence of element from a list using removeAll method 

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
list.add(3,"a");

System.out.println("List before removal of elements");

for(String str : list){
    System.out.println(str);
}
List<String> eleToBeRemoved = new ArrayList<String>();
eleToBeRemoved.add("a");
list.removeAll(eleToBeRemoved);

System.out.println("List after removal of element a");

for(String str : list){
    System.out.println(str);

}

List before removal of elements
a
b
c
a
List after removal of element a
b
c

Removing multiple occurrences of multiple elements using removeAll method 

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
list.add(3,"a");
list.add(4,"b");

System.out.println("List before removal of elements");

for(String str : list){
     System.out.println(str);
}
List<String> eleToBeRemoved = new ArrayList<String>();
eleToBeRemoved.add("a");
eleToBeRemoved.add("b");
list.removeAll(eleToBeRemoved);

System.out.println("List after removal of element a");

for(String str : list){
      System.out.println(str);

}

Output :
List before removal of elements
a
b
c
a
b
List after removal of element a
c

Removing element from a specific index using remove method

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
 
System.out.println("List before removal of element");

for(String str : list){
   System.out.println(str);
}
list.remove(1);
System.out.println("List after removal of element at index 1");

for(String str : list){
   System.out.println(str);
}

Ouput :
List before removal of element
a
b
c
List after removal of element at index 1
a
c

Retaining only particular elements in the list and removing rest using retainAll method

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
list.add(3,"d");
list.add(4,"e");
 
System.out.println("Original List before call to retainAll....");
ListIterator lstitr = list.listIterator();
while(lstitr.hasNext()){
 System.out.print("Index:"+lstitr.nextIndex()+"\t");
        String str  = (String)lstitr.next();
 System.out.print("Elemnent:"+str);
 System.out.println();
}
 
System.out.println("Retain All..............");
List<String> retainList = new ArrayList<String>();
retainList.add("d");
retainList.add("e");
System.out.println("List of elements to be retained");
ListIterator lstitr1 = retainList.listIterator();
while(lstitr1.hasNext()){
 System.out.print("Index:"+lstitr1.nextIndex()+"\t");
        String str  = (String)lstitr1.next();
 System.out.print("Elemnent:"+str);
 System.out.println();
}
list.retainAll(retainList);
System.out.println("Original List after call to retainAll....");
ListIterator lstitr2 = list.listIterator();
while(lstitr2.hasNext()){
 System.out.print("Index:"+lstitr2.nextIndex()+"\t");
        String str  = (String)lstitr2.next();
 System.out.print("Elemnent:"+str);
 System.out.println();

}

Output :
Original List before call to retainAll....
Index:0 Elemnent:a
Index:1 Elemnent:b
Index:2 Elemnent:c
Index:3 Elemnent:d
Index:4 Elemnent:e
Retain All..............
List of elements to be retained
Index:0 Elemnent:d
Index:1 Elemnent:e
Original List after call to retainAll....
Index:0 Elemnent:d
Index:1 Elemnent:e

So from above example we can see that only element which were there in the retainList are retained in the original list and rest are removed.

What if we retainList have elements which are not present in the original list

List<String> list = new ArrayList<String>();
list.add(0,"a");
list.add(1,"b");
list.add(2,"c");
list.add(3,"d");
list.add(4,"e");
 
System.out.println("Original List before call to retainAll....");
ListIterator lstitr = list.listIterator();
while(lstitr.hasNext()){
 System.out.print("Index:"+lstitr.nextIndex()+"\t");
        String str  = (String)lstitr.next();
 System.out.print("Elemnent:"+str);
 System.out.println();
}
 
System.out.println("Retain All..............");
List<String> retainList = new ArrayList<String>();
retainList.add("f");
retainList.add("g");
System.out.println("List of elements to be retained");
ListIterator lstitr1 = retainList.listIterator();
while(lstitr1.hasNext()){
 System.out.print("Index:"+lstitr1.nextIndex()+"\t");
        String str  = (String)lstitr1.next();
 System.out.print("Elemnent:"+str);
 System.out.println();
}
list.retainAll(retainList);
System.out.println("List size after call to retainAll:"+list.size());
System.out.println("Original List after call to retainAll....");

ListIterator lstitr2 = list.listIterator();
while(lstitr2.hasNext()){
 System.out.print("Index:"+lstitr2.nextIndex()+"\t");
 String str  = (String)lstitr2.next();
 System.out.print("Elemnent:"+str);
 System.out.println();

}
System.out.println("Nothing");

Output :
Original List before call to retainAll....
Index:0 Elemnent:a
Index:1 Elemnent:b
Index:2 Elemnent:c
Index:3 Elemnent:d
Index:4 Elemnent:e
Retain All..............
List of elements to be retained
Index:0 Elemnent:f
Index:1 Elemnent:g
List size after call to retainAll:0
Original List after call to retainAll....
Nothing

From above example we can see that as elements f and g which we wanted to retain were not there in the original list,so there is basically nothing to be retained from original list,hence all the elements from original list are removed.We checked size also after we made call to retainAll,it verifies that original list does not have any element in it after call to retainAll.



That's all on Write operations on ArrayList. For read operations on ArrayList,please read ArrayList Read Operations explored.Hope this article was helpful to you guys.Any suggestions,questions are welcome.