Because arrays kinda suck.
Arrays in Java are fairly primitive:
Size fixed at creation
Cannot add or remove elements other than by copying everything up or down
No methods
Java has a rich collections library that lives in the package java.util.
We’re going to talk about just two parts of that library: List and ArrayList.
java.util.ListList is an interface which is a thing we’ll talk about in more detail later in the year.
Remember when I said everything in Java is a class?
I lied.
Interfaces are like classes in that they define a new type and a set of methods.
But they (mostly) don’t contain any code that does anything.
java.util.ArrayListArrayList is a class.
In fact there’s nothing special about it; you could write it yourself if it didn’t exist as part of Java’s standard library.
It implements the List interface.
There are other classes that implement List.
This is better than Javascript where there’s just one array type.
If you are about to write a class that seems generally useful, you should check the JDK documentation, Google, or ask a robot to see if there is a class already built into Java that does what you need.
The complete documentation of any class in the JDK can be found in the official Javadocs.
Javadocs document exactly the publicly accessible parts of a class—variables, constructors, and methods—that you need to know about to use it.
Here are the Here are the List Javadocs and the ArrayList Javadocs

<E> thing?List is a generic type meaning we can describe the behavior of an List without regard to what particular type of object it might hold.
E is called the type parameter and is a stand-in for the type of element that we will specify and is used in the signature’s of the List methods like this:
boolean add(E e) // add an element of type E to the list
E get(int index) // get an element of type E from the list
List typesList<String> - contains Strings.
List<Point> - contains Points.
You can read List<String> as “a List of Strings” just like String[] is “an array of Strings.”
For the same reason we declare variables to be the specific type of the values we are going to store in them, it’s useful to declare the type of object we intend to put in a given array list. Consider:
List<String> strings = ...;
String upper = strings.get(0);
Because strings is declared to be a List<String> we—and the compiler—know the element returned by get will in fact be a String.

Note the List<E> in the list of “All Implemented Interfaces”.
List<String> strings = new ArrayList<>();
To the compiler, the variable strings is of type List<String> which means we can only do things with it that are defined in the List<E> interface.
But at runtime it is actually an instance of the class ArrayList so what the list methods actually do is determined by that class.
ListsList<String> strings = new LinkedList<>();
Creates an instance of a different class that also implements the List interface.
Like most well-designed classes, ArrayList has no public instance variables. It also has no static variables.
But it doesn’t really matter because variables are not part of interfaces so if we declare a variable as List<String> we can only do things with it defined in the interface.
ArrayListWe only have to specify the type of element when declaring the variable. In the constructor we just need a pair of <>:
List<String> strings = new ArrayList<>(); // ✅
You can redundantly specify it:
List<String> strings = new ArrayList<String>(); // 🆗
Don’t do this as it makes something called a raw type and the compiler will yell at you.
List<String> strings = new ArrayList(); // ☠️☠️☠️:
You will almost always use the no-argument constructor which constructs an empty array list.
List<String> strings = new ArrayList<>();
List<Integer> numbers = new ArrayList<>();
There’s another constructor that takes a collection as its argument which can be used to make a new ArrayList that contains the same elements as another:
// Make an ArrayList and add some elements
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
// Make a new ArrayList containing the same elements
List<String> copy = new ArrayList<>(strings);
List.ofAnother way to make a list is with the static method List.of:
List<String> strings = List.of("a", "b", "c");
However, the list is not an ArrayList. In fact it is an instance of some unknown-to-us class whose instances are immutable.
Which is often good. Immutability is actually great when you want it.
But if we want to make an ArrayList concisely we can combine List.of with the copy constructor:
List<String> foo = new ArrayList<>(List.of("a", "b", "c"));
Makes a new ArrayList containing the strings "a", "b", and "c".
The ArrayList is mutable.
If you look at the Javadocs you will see there’s a third constructor that takes an int argument.
List<String> lots = new ArrayList<>(1_000_000);
That constructor makes an ArrayList with an initial underlying array of the given size. But the size() of the ArrayList is still 0.
It’s purely an optimization for when you know you are going to put a lot of elements into an ArrayList as it avoids repeatedly increasing the capacity of the list as you add more items to it.
List methodsBasic methods
int size() |
Number of elements in list. |
add(E obj) |
Adds obj to list. |
add(int i, E obj) |
Adds obj at index i. |
E get(int i) |
Returns value at index i |
E set(int i, E obj) |
Sets value at index i to obj. |
E remove(int i) |
Removes element at index i. |
E gets filled inIn, for instance, a List<String> these become:
int size() |
add(String s) |
add(int i, String s) |
String get(int i) |
String set(int i, String s) |
String remove(int i) |
You can declare a variable as just List. This is called the “raw type” and it can hold any kind of reference type. But you shouldn’t ever use raw types.
For historical reasons, the type parameters in generic types like List<E> and ArrayList<E> have to be reference types.
ints, doubles, and booleans are not reference types so we can’t make Lists of them.
Instead, Java includes classes called “wrapper types” or “boxed types” that wrap up primitive values to be used with Lists and other generic classes that deal only with objects.
List<Integer>To make a list of integers we must declare its element type to be Integer.
But luckily something called autoboxing will almost always take care of translating between int and Integer for you.
List<Integer> nums = new ArrayList<>();
nums.add(42); // boxed into Integer.valueOf(42)
nums.add(100); // boxed into Integer.valueOf(100)
// Boxed values are unboxed so we can use them as
// operands to + which produces an actual `int`.
int sum = nums.get(0) + nums.get(1);
nums.add(sum); // sum is then boxed.
ArrayList vs arraysArrays are the only type we can use [] with.
ArrayList is a class so everything we do with it is done with methods.
ArrayLists are mutable both in the sense that we can change individual elements (which we can also do with arrays) but also we can add and remove elements and change the size of the list.
Lists can be mutable or immutableNot all implementation of List are mutable.
Part of the point of interfaces is they let us pick an implementation that has specific characteristics we care about.
ArrayList is conceptually pretty simple.
Under the covers it’s just using an array to hold its elements.
But it keeps track of how many slots in the array have been used and when it needs to expand, it allocates a new array and copies everything from the old array to the new one and then swaps in the new one.
new String[size] |
new ArrayList<String>() |
arr.length |
list.size() |
arr[i] |
list.get(i) |
arr[i] = x |
list.set(i, x) |
Note there are no array analogs for add and remove since arrays can’t change size.
There are quite a few other useful method that you can look up in the Javadocs.
ListsFor the next few slides assume we’ve declared and initialized this variable:
List<String> strings
for (int i = 0; i < strings.size(); i++) {
doWhatever(strings.get(i));
}
This is just like the canonical for loop over an array except we’ve replaced .length with .size() and [i] with .get(i).
for (String s: strings) {
doWhatever(s);
}
Lists are written so they can be used with the enhanced for loop.
(You can write your own classes that could be used with the enhanced for loop but doing so is outside the AP curriculum.)
ArrayList is a very useful class and in real programs you’d likely take advantage of the many methods described in the Javadocs plus its relation to other classes in the java.util package.