4.8. ArrayList and its Methods¶
Figure 1: A couple of lists¶
At the beginning of this unit, we learned about using arrays to hold collections of related data. However arrays are not very flexible. Most notably, the size of an array is established at the time of creation and cannot be changed. What if you don’t know how big the collection of data will be? What if you want to both add and remove items from a collection? For example, if you wanted to represent a shopping list, you might add to the list throughout the week and remove things from the list while you are shopping. You probably would not know how many items will be on the list at the beginning of the week.
For cases like this, Java has a class called ArrayList which is a re-sizable
list. It is called ArrayList because it stores the items that have been
added to it in an underlying array. But it also takes care of keeping track of
how many items have been added to the array and it will create a new bigger
array under the covers when needed to hold more items.
You can use ArrayList instead of arrays whenever you don’t know the size of
the array you need or you know that you will add and remove items and may need
to change the array’s size dynamically during run time. An ArrayList is
mutable in size and contains object references, meaning it can change during run time by adding and removing objects from it.
Note
An ArrayList is often called just a list. Prior to 2020
the AP CSA curriculum included interfaces which are somewhat like classes
and the interface List was often used to declare a variable that would
refer to an ArrayList. Interfaces are no longer on the exam, but if you
see List being used in an old exam question just assume it’s an
ArrayList.
- An ArrayList will always use less memory than an array.
- No, An ArrayList grows as needed and is typically bigger than the data put into it. If the underlying array in an ArrayList is full when adding in new data, it usually doubles in size.
- An ArrayList can store objects, but arrays can only store primitive types.
- No, you can have an array of objects.
- An ArrayList has faster access to the last element than an array.
- No, an ArrayList is implemented using an array so it has the same access time to any index as an array does.
- An ArrayList resizes itself as necessary as items are added, but an array does not.
- An ArrayList is really a dynamic array (one that can grow or shrink as needed).
4-8-1: Which of the following is a reason to use an ArrayList instead of an array?
4.8.1. import java.util.ArrayList¶
The ArrayList class is in the java.util package. A package is a set
or library of related classes. The classes we have used until now, such as
String and Math, are in the special package java.lang whose classes
are always available in any Java program. Other packages, such as java.util,
provide classes that can only be used either by importing them or (much more
rarely) by referring to them by their full name which includes the package as a
prefix. The full name of ArrayList is thus java.util.ArrayList but
rather than type that out all the time, in any class where we want to use
ArrayList we will usually import it with an import statement.
Import statements have to come before the class definition in a Java source file
and serve to tell Java which class you mean when you use a short name like
ArrayList. To import just one class we use a single import of the
fully-qualified name of the class like this:
// Import just the ArrayList class from java.util
import java.util.ArrayList;
After such an import statement, anywhere ArrayList is used as a class name
in the file it will be taken to mean java.util.ArrayList.
Another option is to import all the classes in a package with a “wildcard” import:
// Import everything in java.util including ArrayList
import java.util.*;
This import statement will also cause, ArrayList to refer
java.util.ArrayList. But many other names of classes defined in the
java.util package will also be available whether you use them or not. (One
that you have probably used by now is Scanner which can be used to read
input a user types at the command line.) Using wildcard imports can cause
conflicts if you import all the classes from two different packages and they
have class names in common but usually that’s not a problem, at least with
packages that are part of Java itself.
Note
Don’t worry about adding import statements on the AP CSA exam. Any that you need will be provided for you.
- You can only have one import statement in a source file.
- You can have an many import statements as you need.
- You must specify the class to import.
- You can use * to import all classes at the specified level.
- Import statements must be before other code in a Java source file.
- Import statements have to be the first Java statements in a source file.
- You must import java.lang.String to use the short name of String.
- You do not have to import any classes that are in the java.lang package.
4-8-2: Which of the following is true about import statements?
4.8.2. Declaring and Creating ArrayLists¶
To declare an ArrayList use ArrayList<Type> name where Type, called a
type parameter is the type of objects you want to store in the ArrayList.
For example a variable naming an ArrayList meant to hold Strings is
declared as ArrayList<String> as shown in the code below. Programmers use the letter E and call it the generic type for an Element. ArrayList<E>, where the generic type E specifies the type of the elements. (Without it, the type will be Object). When ArrayList<E> is specified, the types of the reference parameters and return type when using its methods are type E. ArrayList<E>, where the generic type E specifies the type of the elements. So if E is String, then the type of the reference parameters and return type when using its methods are type String.
You can declare a variable to just be of type ArrayList, with no type parameter, and it’ll be approximately the same as if you had declared ArrayList<Object>, but it is good practice to specify the type of objects you intend to store in an
ArrayList as it allows the compiler to find errors (that are specific to that to Strings or ints or whatever type you put in) that would otherwise be
missed until run time.
// ArrayList<Type> name = new ArrayList<Type>();
// An ArrayList of Strings:
ArrayList<String> shoppingList = new ArrayList<String>();
As with other reference types, declaring a ArrayList variable doesn’t
actually create a ArrayList object. It only creates a variable that can
refer to a ArrayList or null. To actually create a ArrayList we must
invoke a constructor such as new ArrayList<String>(). The ArrayList constructor ArrayList() constructs an empty list.
You can get the number of items in a ArrayList using the size() method.
Notice that a newly constructed ArrayList is empty and thus has a size of 0.
Also remember that you can’t call methods on null so trying to call size
on the value of list2 at line 10 below causes a NullPointerException.
The following code demonstrates a NullPointerException. Change the list2 declaration so that it creates a new ArrayList to remove the NullPointerException.
You can also create ArrayLists of integer and double values. However, you have
to use the wrapper classes Integer or Double as the type parameter because ArrayLists
can only hold objects, not primitive values. All primitive types must be
wrapped in objects before they are added to an ArrayList. For example,
int values can be wrapped in Integer objects, double values can be
wrapped in Double objects. However this normally happens automatically
thanks to autoboxing.
You can actually put in any kind of objects in an ArrayList, including
instances of classes that you write, such as the Student, Person, or
Pet classes.
// An ArrayList of Integers:
ArrayList<Integer> numList = new ArrayList<Integer>();
// An ArrayList of Student objects:
ArrayList<Student> roster = new ArrayList<Student>();
- ArrayList[int] numbers = new ArrayList();
- The square brackets [] are only used with arrays, not ArrayLists.
- ArrayList<String> numbers = new ArrayList();
- String is not the correct type since this is for an array of integers, and the type should be next to ArrayList on both sides.
- ArrayList<int> numbers = new ArrayList<int>();
- ArrayLists cannot hold primitive types like int. You must use the wrapper class Integer.
- ArrayList<Integer> numbers = new ArrayList<Integer>();
- The wrapper class Integer is used to hold integers in an ArrayList.
4-8-4: Which of the following is the correct way to create an ArrayList of integers?
4.8.3. ArrayList Methods¶
The following are the ArrayList methods that you need to know for the AP CSA
exam. These are included on the AP CSA Java Quick Reference Sheet that you will receive
during the exam so you do not need to memorize them. The E in the method headers
below stands for the type of the element in the ArrayList; this type E can be
any Object type. We will look at how these methods work below.
int size() returns the number of elements in the list
boolean add(E obj) appends obj to the end of the list and returns true
E remove(int index) removes the item at the index and shifts remaining items to the left (to a lower index)
void add(int index, E obj) moves any current objects at index or beyond to the right (to a higher index) and inserts obj at the index
E get(int index) returns the item in the list at the index
E set(int index, E obj) replaces the item at index with obj
4.8.4. size()¶
You can get the number of items in a ArrayList
using its size() method. The ArrayList starts out empty with a size
of 0.
ArrayList<String> list = new ArrayList<String>();
System.out.println( list.size() );
Note
With arrays, you use the length field to get the number of items in the
array. But, with an ArrayList you use the size() method to get the
number of items in the ArrayList. You will not be penalized if you mix up
length and size() in the CSA exam. The number of items in an empty
ArrayList is 0.
4.8.5. add(obj)¶
You can add values to an ArrayList using the method add(obj) which will
add the object to the end of the list, just like you would join the end of the
line to board a bus. Note that we can add objects of any type to an
ArrayList. The following code has a String list and an Integer list.
Can you add another item to the shopping list and print out the new list?
Primitive types like int and double are automatically converted to their corresponding wrapper classes Integer and Double using autoboxing when added to an ArrayList. When you pull an int value out of a list of Integers
that is called unboxing.
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(new Integer(5)); // this will work in Java 7
list.add(5); // this will work in all Java versions
You can put any kind of objects into an ArrayList. Even instances of a class
that you wrote. For example, here is an ArrayList of Students.
An example of an ArrayList of Student objects. Add a new student with
your name and info in it.
4.8.6. add(index,obj)¶
There are actually two different add methods in the ArrayList class. The
add(obj) method adds the passed object to the end of the list. The
add(index,obj) method adds the passed object at the passed index, but first
moves over any existing values to higher indices to make room for the new
object. The indices for an ArrayList start at 0 and end at the number of elements - 1.
What will the code below print out? Try figuring it out before running it.
Remember that ArrayLists start at index 0 and that the add(index,obj) always
has the index as the first argument.
Note
ArrayLists like arrays start numbering their elements from 0.
- [1, 2, 3, 4, 5]
- This would be true if all the
addmethod calls wereadd(value), but at least one is not. - [1, 4, 2, 3, 5]
- This would be true if it was
add(1, 4) - [1, 2, 4, 3, 5]
- The
add(2, 4)will put the 4 at index 2, but first move the 3 to index 3. - [1, 2, 4, 5]
- This would be true if the
add(2, 4)replaced what was at index 2, but it actually moves the value currently at index 2 to index 3.
4-8-8: What will print when the following code executes?
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(2, 4);
list1.add(5);
System.out.println(list1);
You can step through the code above by clicking on this Java Visualizer.
- ["Anaya", "Sarah", "Layla", "Sharrie"]
- The
add(1, "Sarah")will move any current items to the right and then put "Sarah" at index 1. - ["Anaya", "Layla", "Sharrie", "Sarah"]
- This would be true if the last one was
add("Sarah") - ["Sarah", "Anaya", "Layla", "Sharrie"]
- This would be true if the last one was
add(0, "Sarah") - ["Anaya", "Layla", "Sarah", "Sharrie"]
- This would be true if the last one was
add(2, "Sarah")
4-8-9: What will print when the following code executes?
ArrayList<String> list1 = new ArrayList<String>();
list1.add("Anaya");
list1.add("Layla");
list1.add("Sharrie");
list1.add(1, "Sarah");
System.out.println(list1);
You can step through the code above by clicking on the following Java Visualizer.
4.8.7. remove(index)¶
You can also remove values from an ArrayList using the remove(index)
method. It removes and returns the item at the given index. This will move all
the other items over in the underlying array and decrease the size of the
ArrayList by 1.
What will the following code print out? Try to guess before you run it. Were you surprised? Read the note below.
Note
The remove(int index) method will remove the object at the given index
and shift left any values to the right of that index. It doesn’t remove the
object that matches the integer value given. In the example above it doesn’t
remove the value 1. It removes the value 2 at index 1.
- [2, 3]
- This would be true if it was
remove(0) - [1, 2, 3]
- The
removewill remove a value from the list, so this can't be correct. - [1, 2]
- The 3 (at index 2) is removed
- [1, 3]
- This would be true if it was
remove(1)
4-8-11: What will print when the following code executes?
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.remove(2);
System.out.println(list1);
You can step through the code above by clicking on the following RemoveExample.
4.8.8. get(index) and set(index, obj)¶
You can get the object at an index using obj = listName.get(index) and set
the object at an index using listName.set(index,obj). Both methods require
that the index argument refer to an existing element of the list, i.e. the index
must be greater than or equal to 0 and less than the size() of the list.
Notice that ArrayLists use get and set methods instead of the
index operator that we use with arrays: array[index]. This is because
ArrayList is a class with methods, not a built in type with special support
in the language like arrays.
Try to guess what the code below will print before running it. Can you get the last element in the nameList to print it out? Can you set the first element in the list to your name and print out the list?
- [1, 2, 3, 4, 5]
- The
setwill replace the item at index 2 so this can not be right. - [1, 2, 4, 5, 6]
- The
addwith an index of 2 and a value of 5 adds the 5 at index 2 not 3. Remember that the first index is 0. - [1, 2, 5, 4, 6]
- The
setwill change the item at index 2 to 4. The add of 5 at index 2 will move everything else to the right and insert 5. The lastaddwill be at the end of the list. - [1, 5, 2, 4, 6]
- The
addwith an index of 2 and a value of 5 adds the 5 at index 2 not 1. Remember that the first index is 0.
4-8-13: What will print when the following code executes?
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.set(2, 4);
list1.add(2, 5);
list1.add(6);
System.out.println(list1);
You can step through the code above by clicking on the following Example1.
- ["Sarah", "Destini", "Layla", "Sharrie"]
- Remember that the first index is 0 not 1.
- ["Sarah", "Destini", "Anaya", "Layla", "Sharrie"]
setchanges the value and the first index is 0 not 1.- ["Anaya", "Sarah", "Sharrie"]
addat index 1 adds the new value at that index but moves right any existing values.- ["Anaya", "Sarah", "Destini", "Sharrie"]
- The list is first ["Anaya", "Layla", "Sharrie"] and then changes to ["Anaya", Destini", "Sharrie"] and then to ["Anaya", "Sarah", "Destini", "Sharrie"]
4-8-14: What will print when the following code executes?
List<String> list1 = new ArrayList<String>();
list1.add("Anaya");
list1.add("Layla");
list1.add("Sharrie");
list1.set(1, "Destini");
list1.add(1, "Sarah");
System.out.println(list1);
You can step through the code above by clicking on the following Example2.
4.8.9. Comparing arrays and ArrayLists¶
When do you use arrays and when do you use ArrayLists? Use an array when
you want to store several items of the same type and you know how many items
will be in the array and the items in the array won’t change in order or number.
Use an ArrayList when you want to store several items of the same type and
you don’t know how many items you will need in the list or when you want to
remove items from the list or add items to the list while the program is
running.
Here is a comparison of how to create arrays and ArrayLists:
// arrays must specify a size!
int[] highScores = new int[5];
String[] names = new String[5];
// ArrayLists are empty to start with
ArrayList<Integer> highScoreList = new ArrayList<Integer>();
ArrayList<String> nameList = new ArrayList<String>();
Here is a comparison of how to access and change elements in arrays and
ArrayLists. Note that ArrayLists have a method size() instead of a
length property, and ArrayLists use get/set methods instead of
the index operator ([]).
Operation |
array |
ArrayList |
|---|---|---|
length/size |
array.length |
list.size() |
Access |
value = array[index]; |
value = list.get(index); |
Modify |
array[index] = value; |
list.set(index,value); |
Note that the ArrayList methods add and remove do not have a simple
equivalent in arrays because they change the number of elements in the list and
may shift the positions of other elements.
Here is a comparison handout of the basic operations to access 1-dimensional
and 2-dimensional arrays (which we will see in the next lessons), ArrayLists,
and Strings made by AP CSA teacher Sam Procopio of Bishop Blanchet High
School.
Rewrite the following code that uses an array to use an ArrayList
instead. In the comments write why you think an ArrayList is a better
data structure to use than an array for this problem.
Although it is not on the AP exam, you can convert an array to a List using
the static method asList from the Arrays helper class:
Arrays.asList(arrayname). Note that ArrayList has a toString method
that is automatically called to print the list in a nice format.
Example code creating an ArrayList from an array.
4.8.10.
Coding Challenge : FRQ Digits¶
This coding challenge is based on the 2017 Free Response Question part 1a on the 2017 AP CSA
exam. In this question, you are asked to write a constructor for a class called
Digits. This constructor takes an integer number as its argument and divides
it up into its digits and puts the digits into an ArrayList. For example,
new Digits(154) creates an ArrayList with the digits [1, 5, 4].
First, let’s discuss how to break up a number into its digits. Try the code
below. What happens if you divide an integer by 10? Remember that in integer
division the result truncates (cuts off) everything to the right of the decimal
point. Which digit can you get by using % 10 which returns the remainder
after dividing by 10? Try a different number and guess what it will print and
then run to check.
Set number to a different number and guess what number / and % will return. Which operator gives you a digit in number?
We can use a while loop to print out each digit in reverse order starting from the right (4, 5, 1 for the number 154) while dividing it by 10. You can try it in the active code above. Here is the pseudocode:
while number is greater than 0
print out the last digit using %
change the number to cut off the last digit using /
Now, let’s write a constructor for the Digits class that uses this loop and
adds each found digit to the ArrayList instead of printing it out.
Note that this will create the digit list in reverse order. To get the digits in
the right order, you can use the add(index, obj) method to add the digit to
the beginning of the ArrayList instead of the end.
Complete the challenge below to put the digits of a number in an ArrayList.
4.8.11. Summary¶
ArrayLists are re-sizable lists that allow adding and removing items to change their size during run time.
(AP 4.8.A.4) The
ArrayListclass is part of thejava.utilpackage. Animportstatement can be used to make this class available for use in the program.(importjava.util.ArrayListorjava.util.*).(AP 4.8.A.1) An
ArrayListobject is mutable in size and contains object references. (Mutable means that it can change by adding and removing items from it.(AP 4.8.A.2) The
ArrayListconstructorArrayList()constructs an empty list (of size 0).(AP 4.8.A.3) Java allows the generic type
ArrayList<E>, where the generic typeEspecifies the type of the elements. (Without it, the type will beObject). WhenArrayList<E>is specified, the types of the reference parameters and return type when using its methods are typeE.(AP 4.8.A.3)
ArrayList<E>is preferred overArrayList(which creates an list of of typeObject). For example,ArrayList<String> names = new ArrayList<String>();allows the compiler to find errors that would otherwise be found at run time.ArrayLists cannot hold primitive types likeintordouble, so you must use the wrapper classesIntegerorDoubleto put numerical values into anArrayList. However autoboxing usually takes care of that for you.(AP 4.8.A.6) The indices for an
ArrayListstart at0and end at the number of elements- 1.(AP 4.8.A.5) The following ArrayList methods, including what they do and when they are used, are part of the Java Quick Reference:
int size() : Returns the number of elements in the list
boolean add(E obj) : Appends obj to end of list; returns true
void add(int index, E obj) : Inserts obj at position index (0 <= index <= size), moving elements at position index and higher to the right (adds 1 to their indices) and adds 1 to size
remove(int index) — Removes element from position index, moving elements at position index + 1 and higher to the left (subtracts 1 from their indices) and subtracts 1 from size; returns the element formerly at position index
E get(int index) : Returns the element at position index in the list
E set(int index, E obj) : Replaces the element at position index with obj; returns the element formerly at position index


