ArrayList#
The class ArrayList
is a special type of class called a Generic
. In this lesson, we won’t go into the details of how generics work. Instead, we will focus on why and how to use the class ArrayList
.
Overview#
The ArrayList
class provides array like behavior with some added benefits. Its constructor introduces a new syntax that involves <angle brackets>. The easiest way to figure this stuff out is by example.
// We create a new ArrayList capable of holding Strings.
// We must have `<String>` added to the class name.
// The constructor must have <>.
// As all constructors must have, the constructor also has ().
ArrayList<String> list = new ArrayList<>()|
list.add("At index 0");
list.add("At index 1");
// arrays use `.length`. ArrayList uses `.size()`
System.out.printf("The size of our list is %d\n", list.size());
System.out.printf("The first item in our list is %s\n", list.get(0));
A few things to note:
The declaration requires that we provide the type of object in the ArrayList
An
ArrayList
can hold any type of object we want, but it must be anObject
.We don’t provide the size of the array in the constructor.[1] Instead, the size of the list will grow & shrink automatically.
We don’t index into the list as we do in an array. We do not use
[]
. Instead, we use API such asadd
andget
.
More API#
There are many cool things about an ArrayList
:
It holds any
Object
typeIt grows and shrinks automatically for us
It has utility API that provide many useful behaviors
Here are some popular API:
API |
Description |
---|---|
arr.add(object) |
adds an object at the end |
arr.get(index) |
gets the object at index |
arr.set(index, object) |
sets the value at index |
arr.add(index, object) |
insert an object at index |
arr.remove(index) |
removes the object at index |
arr.remove(object) |
removes the object from arr |
arr.size() |
gets the count of elements in arr |
arr.clear() |
removes ALL elements from the array |
arr.contains(object) |
asks if an object is in array using .equals() |
arr.indexOf(object) |
finds index of the object |
arr.isEmpty() |
asks if the array is empty |
Practical Exploration#
Here are just a few ways create an ArrayList
.
// repeat the object type in the constructor's <angle brackets>
ArrayList<Integer> list = new ArrayList<Integer>();
// allow the compiler to infer the object type
ArrayList<Integer> list = new ArrayList<>();
// Assign the ArrayList to the List interface.
// Set ArrayList's initial capacity to 100.
List<Integer> list = new ArrayList<>(100);
// Pass in a fixed-size list into the ArrayList constructor
List<String> list = new ArrayList<>(Arrays.asList("Hello", "World!"));
Wrapper Types#
Generics do not work with primitive types; they must work with Object
types. Java has come to our rescue and made it easy for us to contain primitive types by offering Wrapper Classes for each. Here are the most common: Integer
, Double
, Boolean
and Character
. These classes offer lots of helpful methods.
Key points about these wrapper classes:
All wrapper classes are immutable - their values cannot be changed after creation
All extend
Object
, so they can be used in generic collectionsThey provide useful static methods (like
Integer.parseInt()
,Double.valueOf()
)Autoboxing automatically converts primitives to wrappers:
Integer i = 5;
Auto-unboxing automatically converts wrappers to primitives:
int x = new Integer(5);
All wrapper classes (except
Character
) can be constructed fromString
representationsThey all override
equals()
andtoString()
methods appropriately
Construction of Wrapper Classes#
The Wrapper Classes can be created from a String
by:
valueOf:
Integer i1 = Integer.valueOf("123");
Each wrapper class has a
valueOf
method.
parsing:
Integer i2 = Integer.parseInt("123");
Other wrapper classes have similar, but not identical method names. e.g.
Double.parseDouble
Boxing:
Integer i3 = 4;
A Wrapper class is a class that has very little functionality. Think of it as a gift box that holds the actual item. In this image, we see a wrapper class that holds the primitive int
. To get the primitive value into the wrapper class we have to Box it. To extract the primitive value from the wrapper class we Unbox it.
Boxing & Unboxing#
Boxing and unboxing are Java’s automatic conversion mechanisms between primitive types and their corresponding wrapper classes. Boxing occurs when Java automatically converts a primitive value (like int
, double
, or boolean
) into its wrapper object (like Integer
, Double
, or Boolean
), while unboxing is the reverse process where wrapper objects are automatically converted back to their primitive equivalents.
Understanding boxing and unboxing is crucial because while it makes code more convenient to write, it can impact performance in certain scenarios since object creation and method calls have more overhead than primitive operations.
// This work due to autoboxing/unboxing:
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(42); // autoboxing: int → Integer
// We can also auto-unbox
int value = numbers.get(0); // auto-unboxing: Integer → int
// Explicit Boxing
Integer num = Integer.valueOf(100);
Boolean flag = Boolean.TRUE;
Character ch = Character.valueOf('A');
// Explicit Unboxing
int n = num.intValue();
Oracle’s official documentation, and some technical resources, often reserve Boxing specifically for the automatic (or implicit) conversion done by the compiler. Oracle will not consider “Explict Boxing” as boxing at all. However, there is not concensus on this terminology.
This site has chosen to declare that there are two ways to Box or Unbox:
Implicit or Automatic: The compiler does it automatically for the developer.
Explicit or Manual: The developer explicitly puts the primitive into the Wrapper Class.
What’s so Important?
#
Things to remember:
Creating an
ArrayList
uses <angle brackets> and parentheses. It a bit wonky.Example:
ArrayList<Double> list = new ArrayList<>();
You cannot use
[]
(brackets) on theArrayList
. It is not an actual array.Instead, use the API
add
,get
andset
.Example:
list2.set(2, list1.get(2));
Only
Object
types can be contained inside theArrayList
If you want to store
int
values, use the wrapper classInteger
Java will automatically Box and Unbox primitives for you
Use
size()
to see how many elements are in theArrayList
The ArrayList will automaticall grow and shrink.
list.remove(1);
// removes the element at index 1 and the other elements at index 2+ will slide into place.
Footnotes#
[1] The constructor for ArrayList
can take an integer argument. Most students think that this is the size of the array, and to some degree they’re right! It is the initial size of the underlying array
, but it is not the count of elements currently in the ArrayList
(the value returned by the method size()
). It gets a bit complicated.
// create a list that can hold 101 dalmations
ArrayList<Dog> dalmations = new ArrayList<>(101);
// size() == 0. The capacity of the list starts out as 101.
// This prints: Count of dogs in the list is: 0
System.out.printf("Count of dogs in the list is: %d\n", dalmations.size());
The ArrayList
is implemented with an underlying array
and the size of the underlying array is not the same as the size()
of the ArrayList. The size()
of an ArrayList is the count of elements that have been added to the array that can be safely indexed. When the user adds enough elements to exceed the size of the unerlying array, a new array needs to be constructed, and all the elements in the array need to be copied over. This process is expensive and work is done to minimize the occurance.
The ArrayList
will start off with a default capacity of 10. When the 11th element is added, the ArrayList will double its size to 20. When the 21st element is added, it is doubled again to 40. So on and so forth until the size growth is beyond memory limits.
[2] Arrays.asList
is a convient way to create a List
.
// Use the Arrays helper to create a list tht has a FIXED-SIZED.
// In this List, elements cannot be added or removed.
// This is not an ArrayList. It is a limited List.
List<String> list = Arrays.asList("Hello", "World!");
list.add("Illegal"); // ❌ throws UnsupportedOperationException