Unit 4 · 22 min
4.8 ArrayList Methods
An ArrayList is an array that resizes itself and keeps its elements packed together by shifting them.
Summary, objectives and course and exam description (CED) codes
An ArrayList is an object that holds object references and can grow and shrink, unlike an array. You create an empty one with new ArrayList<E>(), where E is the element type, after importing java.util.ArrayList. The Java Quick Reference methods size, add, get, set and remove work with indexes from 0 to size() - 1, and adding or removing in the middle shifts the later elements.
By the end of this session you can
- 4.8.A Develop code for collections of related objects using ArrayList objects and determine the result of calling methods on these objects.
Reviewed against the CED on
1LearnThe notes, the traps and how to remember them
1. Creating an ArrayList
An ArrayList object is mutable in size (it can grow and shrink) and it contains object references 4.8.A.1. The class is part of the java.util package, so an import statement must make it available 4.8.A.4. The constructor ArrayList() constructs an empty list 4.8.A.2.
Java allows the generic type ArrayList<E>, where the type parameter E is the type of the elements 4.8.A.3. With ArrayList<E>, the parameters and return types of the ArrayList methods are type E. Using ArrayList<E> is preferred over plain ArrayList, because it lets the compiler find errors that would otherwise only be found at run time 4.8.A.3.
import java.util.ArrayList;
public class Playlist
{
public static void main(String[] args)
{
ArrayList<String> songs = new ArrayList<String>();
System.out.println(songs.size());
System.out.println(songs);
}
}
Output:
0
[]
Printing an ArrayList shows its elements in square brackets, separated by commas.
With a type parameter, a wrong type is caught by the compiler:
ArrayList<String> songs = new ArrayList<String>();
songs.add(42);
Compiler error:
error: incompatible types: int cannot be converted to String
Background: without a type parameter, the same kind of mistake compiles and only fails when the program runs. This is why ArrayList<E> is preferred.
ArrayList songs = new ArrayList();
songs.add(42);
String first = (String) songs.get(0);
System.out.println(first);
Output:
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')
Because the elements are object references, a list of numbers uses a wrapper class: ArrayList<Integer> or ArrayList<Double>. Autoboxing and unboxing (topic 4.7) convert for you.
2. size, add and get
These methods are in the Java Quick Reference 4.8.A.5:
int size()returns the number of elements in the list.boolean add(E obj)appendsobjto the end of the list and returnstrue.E get(int index)returns the element at positionindex.
ArrayList<Integer> laps = new ArrayList<Integer>();
laps.add(62); // autoboxing: int 62 becomes an Integer
laps.add(58);
boolean ok = laps.add(60);
System.out.println(ok);
System.out.println(laps.size());
System.out.println(laps.get(1));
int best = laps.get(1); // unboxing
System.out.println(best + 1);
System.out.println(laps);
Output:
true
3
58
59
[62, 58, 60]
| index | 0 | 1 | 2 |
|---|---|---|---|
laps |
62 | 58 | 60 |
3. add at an index: shifting right
void add(int index, E obj) inserts obj at position index, where 0 <= index <= size. The elements at position index and higher move to the right (1 is added to their indices), and 1 is added to the size 4.8.A.5.
ArrayList<String> queue = new ArrayList<String>();
queue.add("Ana");
queue.add("Ben");
queue.add("Cleo");
queue.add(1, "Dev"); // insert at index 1
System.out.println(queue);
queue.add(4, "Eli"); // index == size: same as appending
System.out.println(queue);
System.out.println(queue.size());
Output:
[Ana, Dev, Ben, Cleo]
[Ana, Dev, Ben, Cleo, Eli]
5
| index | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| before | “Ana” | “Ben” | “Cleo” | ||
after add(1, "Dev") |
“Ana” | “Dev” | “Ben” | “Cleo” | |
after add(4, "Eli") |
“Ana” | “Dev” | “Ben” | “Cleo” | “Eli” |
“Ben” was at index 1 and is now at index 2: inserting changed its index.
4. set and remove
E set(int index, E obj)replaces the element at positionindexwithobjand returns the element formerly at that position 4.8.A.5. The size does not change.E remove(int index)removes the element at positionindex, moves the elements atindex + 1and higher to the left (1 is subtracted from their indices), subtracts 1 from the size, and returns the element formerly at that position 4.8.A.5.
ArrayList<String> queue = new ArrayList<String>();
queue.add("Ana");
queue.add("Dev");
queue.add("Ben");
queue.add("Cleo");
String old = queue.set(2, "Bea");
System.out.println(old + " was replaced: " + queue);
String gone = queue.remove(0);
System.out.println(gone + " left: " + queue);
System.out.println("Now first: " + queue.get(0) + ", size " + queue.size());
Output:
Ben was replaced: [Ana, Dev, Bea, Cleo]
Ana left: [Dev, Bea, Cleo]
Now first: Dev, size 3
| index | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
| before | “Ana” | “Dev” | “Ben” | “Cleo” |
after set(2, "Bea") |
“Ana” | “Dev” | “Bea” | “Cleo” |
after remove(0) |
“Dev” | “Bea” | “Cleo” |
Watch out: with an ArrayList<Integer>, remove(1) uses the Quick Reference method remove(int index): it removes the element at index 1, not the value 1.
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(1);
nums.add(5);
nums.add(9);
nums.remove(1);
System.out.println(nums);
Output:
[1, 9]
5. Valid indexes and IndexOutOfBoundsException
The indices of an ArrayList start at 0 and end at the number of elements minus 1 4.8.A.6, so get, set and remove accept 0 to size() - 1. (Only add(index, obj) also accepts size().) Any other index throws an IndexOutOfBoundsException when the code runs.
ArrayList<Double> times = new ArrayList<Double>();
times.add(9.8);
times.add(10.1);
times.add(9.9);
System.out.println(times.get(times.size() - 1));
System.out.println(times.get(times.size()));
Output:
9.9
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3
set cannot grow a list either. On an empty list, set(0, ...) fails because index 0 does not exist yet; use add.
6. Array or ArrayList?
| Task | Array (int[] a) |
ArrayList<Integer> list |
|---|---|---|
| Create | new int[5] or {3, 1, 4} |
new ArrayList<Integer>() (starts empty) |
| Number of elements | a.length |
list.size() |
Read element i |
a[i] |
list.get(i) |
Change element i |
a[i] = 7; |
list.set(i, 7); |
| Add at the end | not possible (fixed length) | list.add(7); |
| Insert or remove in the middle | write your own shift | list.add(i, 7); and list.remove(i); |
| Element types | primitives or references | references only |
| Bad index | ArrayIndexOutOfBoundsException |
IndexOutOfBoundsException |
Lock it in: memory hooks
- add versus setadd squeezes in, set swaps out.
- ShiftingInsert pushes right (+1), remove pulls left (-1).
- SizeArrays have length, Strings have length(), ArrayLists have size().
Common misconceptions
"add(index, obj) replaces the element at that index."
Not quite. add inserts: the element at that index and every element after it move one place right, and the size grows by 1. To replace, use set.
"remove(index) leaves an empty spot."
Not quite. Every element after the removed one moves one place left (its index drops by 1) and the size shrinks by 1. There are no gaps in an ArrayList.
"An ArrayList can store int values."
Not quite. An ArrayList stores object references. Use ArrayList<Integer>; autoboxing turns each int into an Integer when you add it.
"set returns nothing, like a setter."
Not quite. set returns the element that was at that index before it was replaced. remove also returns the element it removed.
Exam traps
- After remove(1), the element that was at index 2 is now at index 1.
- add(size(), obj) is legal (it appends), but get(size()) throws an IndexOutOfBoundsException.
- On an ArrayList<Integer>, remove(1) removes the element at index 1, not the value 1.
- set(i, obj) on an empty list throws an exception: set never grows the list.
2PracticeRecall it, then check yourself
In 30 seconds
- An ArrayList is mutable in size and contains object references.
- new ArrayList<E>() constructs an empty list; E is the element type and is checked by the compiler.
- Import java.util.ArrayList before using it.
- size(), add(obj), add(index, obj), get(index), set(index, obj), remove(index) are in the Java Quick Reference.
- add(index, obj) shifts later elements right; remove(index) shifts them left; set and remove return the old element.
- Valid indexes are 0 to size() - 1; add(index, obj) also allows index == size().
Cover this list, say the points out loud, then take the checkpoint without scrolling back up.
Checkpoint · 5 questions
Checkpoint: ArrayList Methods
Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.
3PrevailLock it in for exam day
By the numbers
- ArrayList constructor and methods in the Java Quick Reference seven members CED 4.8.A.2, 4.8.A.5
- Methods that shift elements and change the size two methods CED 4.8.A.5
Key terms: flip the cards
Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.
-
ArrayListtap to flip
A java.util class for a list of object references that can grow and shrink; ArrayList<E> names the element type E.
Example and CED codes -
ArrayList methodstap to flip
The Java Quick Reference ArrayList methods: size, add(obj), add(index, obj), get, set and remove; add and remove at an index shift later elements.
Example and CED codes -
IndexOutOfBoundsExceptiontap to flip
The run-time exception thrown when an ArrayList method gets an index outside its valid range, such as get(size()).
Example and CED codes -
Integer (class)tap to flip
The java.lang wrapper class whose immutable objects hold one int value; Integer.parseInt(s) returns a String as an int.
Example and CED codes -
Autoboxingtap to flip
The automatic conversion the compiler makes from a primitive value to its wrapper class object, such as int to Integer or double to Double.
Example and CED codes -
Indextap to flip
The position of a character in a String, counted from 0. Valid indices run from 0 to length() - 1.
Example and CED codes -
Arraytap to flip
An object that stores a fixed number of values of the same type, either primitive values or object references, reached by an index.
Example and CED codes -
Reference typetap to flip
A data type used to define objects, that is, anything that is not a primitive type. Every class defines a reference type.
Example and CED codes
Questions students ask
What is the difference between an array and an ArrayList?
An array has a fixed length, can hold primitives, and uses [] and .length. An ArrayList can grow and shrink, holds only object references, and uses get, set, add, remove and size().
What does ArrayList add(index, obj) do?
It inserts obj at that index, moves the element that was there and all later elements one place to the right, and adds 1 to the size. The index can be from 0 to size().
What does ArrayList remove return?
remove(index) returns the element that was at that index, after taking it out and moving all later elements one place left.
Why use ArrayList<String> instead of plain ArrayList?
With the type parameter, the compiler checks every add, get and set, so type mistakes are found when you compile instead of when the program runs.