OCA Java SE 8 Core Java APIs - Java ArrayList








ArrayList can change size at runtime as needed.

An ArrayList is a sequence that allows duplicates.

Creating an ArrayList

There are three ways to create an ArrayList:

The following line creates an ArrayList containing space for the default number of elements without filling any slots yet.

ArrayList list1 = new ArrayList(); 

The following constructor creates an ArrayList containing a specific number of slots without assigning any.

ArrayList list2 = new ArrayList(10); 

The following constructor makes a copy of another ArrayList. We copy both the size and contents of that ArrayList.

ArrayList list3 = new ArrayList(list2); 

Java generics allows you to specify the type of class that the ArrayList will contain.

ArrayList<String> list4 = new ArrayList<String>(); 
ArrayList<String> list5 = new ArrayList<>(); 

Java can tell the compiler what the type would be stored in ArrayList by specifying it between < and >.

We can even omit that type from the right side.

The < and > are still required, though.

This is called the diamond operator because <> looks like a diamond.

ArrayList implements an interface called List.

An ArrayList is a List.

We can store an ArrayList in a List reference variable but not vice versa.

List<String> list6 = new ArrayList<>(); 
ArrayList<String> list7 = new List<>(); // DOES NOT COMPILE 




Using an ArrayList

E is used by convention in generics to mean "any class that this array can hold."

If you didn't specify a type when creating the ArrayList, E means Object. Otherwise, it means the class you put between < and >.

ArrayList implements toString() so you can see the contents by printing it.

add()

The add() methods insert a new value in the ArrayList. The method signatures are as follows:

boolean add(E element) 
void add(int index, E element) 

The following code shows how to use the add method.

ArrayList list = new ArrayList(); 
list.add("A");          // [A] 
list.add(Boolean.TRUE);    // [A, true] 
System.out.println(list);  // [A, true] 

add() stores the String to ArrayList. It then does the same thing for the boolean.

This is okay because we didn't specify a type for ArrayList; therefore, the type is Object, which includes everything except primitives.

Let's use generics to tell the compiler we only want to allow String objects in our ArrayList:

ArrayList<String> safer = new ArrayList<>(); 
safer.add("A"); 
safer.add(Boolean.TRUE);    // DOES NOT COMPILE 

This time the compiler knows that only String objects are allowed in and prevents the attempt to add a boolean.

The following code shows how to try adding multiple values to different positions.

4: List<String> birds = new ArrayList<>(); 
5: birds.add("A");            // [A] 
6: birds.add(1, "B");        // [A, B] 
7: birds.add(0, "C");     // [C, A, B] 
8: birds.add(1, "D");     // [C, D, A, B] 
9: System.out.println(birds);    // [C, D, A, B] 




remove()

The remove() methods remove the first matching value in the ArrayList or remove the element at a specified index.

The method signatures are as follows:

boolean remove(Object object) 
E remove(int index)

The boolean return value tells us whether a match was removed.

The E return type is the element that actually got removed.

The following shows how to use these methods:

3: List<String> myList = new ArrayList<>(); 
4: myList.add("A");     // [A] 
5: myList.add("A");     // [A, A] 
6: System.out.println(myList.remove("D")); // prints false 
7: System.out.println(myList.remove("A")); // prints true 
8: System.out.println(myList.remove(0)); // prints A 
9: System.out.println(myList);     // [] 

Line 6 tries to remove an element that is not in myList. It returns false because no such element is found.

Line 7 tries to remove an element that is in myList and so returns true. Notice that it removes only one match.

Line 8 removes the element at index 0, which is the last remaining element in the ArrayList.

Calling remove() with an int index may throw an exception if the index doesn't exist.

For example, myList.remove(100) throws an IndexOutOfBoundsException.

set()

The set() method changes one of the elements of the ArrayList without changing the size.

The method signature is as follows:

E set(int index, E newElement) 

The E return type is the element that got replaced.

The following shows how to use this method:

1: List<String> myList = new ArrayList<>(); 
2: myList.add("A");                    // [A] 
3: System.out.println(myList.size());     // 1 
4: myList.set(0, "B");               // [B] 
5: System.out.println(myList.size());     // 1 
6: myList.set(1, "B");               // IndexOutOfBoundsException 

Line 2 adds one element to the array, making the size 1.

Line 4 replaces that one element and the size stays at 1.

Line 6 tries to replace an element that isn't in the ArrayList.

Since the size is 1, the only valid index is 0.

Java throws an exception because this isn't allowed.

isEmpty() and size()

The isEmpty() and size() methods look at how many of the slots are in use. The method signatures are as follows:

boolean isEmpty() 
int size() 

The following shows how to use these methods:

System.out.println(myList.isEmpty());     // true 
System.out.println(myList.size());     // 0 
myList.add("A");                    // [A] 
myList.add("A");                    // [A, A] 
System.out.println(myList.isEmpty());     // false 
System.out.println(myList.size());     // 2 

At the beginning, myList has a size of 0 and is empty. It has a capacity that is greater than 0.

After adding elements, the size becomes positive and it is no longer empty.

clear()

The clear() method provides an easy way to discard all elements of the ArrayList. The method signature is as follows:

void clear() 

The following shows how to use this method:

List<String> myList = new ArrayList<>(); 
myList.add("A");                    // [A] 
myList.add("A");                    // [A, A] 
System.out.println(myList.isEmpty());     // false 
System.out.println(myList.size());     // 2 
myList.clear();                         // [] 
System.out.println(myList.isEmpty());     // true 
System.out.println(myList.size());     // 0 

After we call clear(), myList is back to being an empty ArrayList of size 0.

contains()

The contains() method checks whether a certain value is in the ArrayList. The method signature is as follows:

boolean contains(Object object) 

The following shows how to use this method:

List<String> myList = new ArrayList<>(); 
myList.add("A");                         // [A] 
System.out.println(myList.contains("A")); // true 
System.out.println(myList.contains("B")); // false 

This method calls equals() on each element of the ArrayList to see whether there are any matches.

equals()

ArrayList has a custom implementation of equals() so you can compare two lists to see if they contain the same elements in the same order.

boolean equals(Object object) 

The following shows an example:

1: List<String> one = new ArrayList<>(); 
2: List<String> two = new ArrayList<>(); 
3: System.out.println(one.equals(two));      // true 
4: one.add("a");                         // [a] 
5: System.out.println(one.equals(two));     // false 
6: two.add("a");                         // [a] 
7: System.out.println(one.equals(two));     // true 
8: one.add("b");                         // [a,b] 
9: two.add(0, "b");                    // [b,a] 
10: System.out.println(one.equals(two));     // false 

On line 3, the two ArrayList objects are equal.

An empty list is certainly the same elements in the same order.

On line 5, the ArrayList objects are not equal because the size is different.

On line 7, they are equal again because the same one element is in each.

On line 10, they are not equal.

The size is the same and the values are the same, but they are not in the same order.

Converting Between array and List

You should know how to convert between an array and an ArrayList.

Let's start with turning an ArrayList into an array:

3: List<String> list = new ArrayList<>(); 
4: list.add("A"); 
5: list.add("B"); 
//an ArrayList converts itself to an array
6: Object[] objectArray = list.toArray(); 
7: System.out.println(objectArray.length);     // 2 
8: String[] stringArray = list.toArray(new String[0]); 
9: System.out.println(stringArray.length);     // 2 

It defaults to an array of class Object.

Line 8 specifies the type of the array and does what we actually want.

When converting from an array to a List, the original array and created array backed List are linked.

When a change is made to one, it is available in the other.

It is a fixed-size list and is also known a backed List because the array changes with it.

0: String[] array = { "A", "B" };     // [A, B] 
1: List<String> list = Arrays.asList(array); // returns fixed size list 
2: System.out.println(list.size());     // 2 
3: list.set(1, "test");          // [A, test] 
4: array[0] = "new";               // [new, test] 
5: for (String b : array) System.out.print(b + " "); // new test 
6: list.remove(1);     // throws UnsupportedOperation Exception 

Line 1 converts the array to a List. Note that it isn't the java.util.ArrayList we've grown used to. It is a fixed-size, backed version of a List. Line 3 is okay because set() merely replaces an existing value.

It updates both array and list because they point to the same data store.

Line 4 also changes both array and list.

Line 5 shows the array has changed to new test.

Line 6 throws an exception because we are not allowed to change the size of the list.

Sorting

Sorting an ArrayList is very similar to sorting an array, just use a different helper class:

import java.util.*;
/*from   w  w w . ja  va 2 s.  co  m*/
public class Main{
   public static void main(String[] argv){
        List<Integer> numbers = new ArrayList<>(); 
        numbers.add(9); 
        numbers.add(5); 
        numbers.add(8); 
        Collections.sort(numbers); 
        System.out.println(numbers); //[5, 8, 9]    
   }
}

The code above generates the following result.