Module lessons (2/2)
Collections and ArrayList
Traditional arrays in Java have a fixed size defined at the time of creation. To work with lists of data whose size can vary dynamically, Java provides the Java Collections Framework. The most commonly used class is ArrayList.
The ArrayList Class and Generics
ArrayList implements a resizable array in memory. To declare an ArrayList, we must specify the type of elements it will contain by enclosing it in angle brackets < >. This feature is called Generics.
To use ArrayList, we must import it at the beginning of the file from java.util.ArrayList.
Declaration and instantiation:
import java.util.ArrayList;
ArrayList<String> shoppingList = new ArrayList<>();
Core Methods
Here are the fundamental operations on an ArrayList:
add(element): Adds an element to the end of the list.get(index): Returns the element at the specified index (0-indexed).size(): Returns the number of elements currently in the list.remove(index): Removes the element at the specified index.
shoppingList.add("Pane");
shoppingList.add("Latte");
System.out.println("Elementi: " + shoppingList.size()); // Prints 2
System.out.println("Primo elemento: " + shoppingList.get(0)); // Prints "Pane"
Iterating Over a List (For-Each)
The for-each loop is the ideal structure to iterate through all elements of a collection:
for (String item : shoppingList) {
System.out.println(item);
}
Array vs ArrayList: Memory and Performance
Although ArrayList is much more flexible than a static array, it comes with performance and memory trade-offs:
- Static Array: It is allocated in a contiguous block of memory, has a fixed size, and accessing elements via index is extremely fast. It stores primitive types directly without overhead.
- ArrayList: Internally, it manages an array that is resized (by creating a new larger array and copying old elements) when its initial capacity (usually 10) is exceeded. Moreover, it only stores object references, introducing memory overhead for each element.
Autoboxing and Unboxing
Since ArrayList can only hold objects, Java automatically performs conversions between primitive types and their respective wrapper classes:
- Autoboxing: Automatic conversion from a primitive type to a wrapper class. For example, when you write
numbers.add(42), Java automatically converts42(int) toInteger.valueOf(42)(Integer). - Unboxing: Automatic conversion from a wrapper class to a primitive type. For example, when you execute
int num = numbers.get(0), Java internally convertsIntegertoint.
Try it yourself
Import ArrayList, declare an ArrayList of String named names. Add Alice and Bob to the list, then print its size using the size() method.
Show hint
Include `import java.util.ArrayList;` at the top. Create the list with `ArrayList<String> names = new ArrayList<>();`, add the elements, and print its size with `names.size()`.
Solution available after 3 attempts
Declare an ArrayList of Integer named numbers, add the number 42, and print it by retrieving it at index 0 using get().
Show hint
Use `ArrayList<Integer> numbers = new ArrayList<>();` (with the Integer wrapper class) and print it with `System.out.println(numbers.get(0));`.
Solution available after 3 attempts
Declare an ArrayList of String named colors. Add the colors Red, Green, and Blue to the list. Finally, use a for-each loop to iterate through the list and print each color to the screen.
Show hint
Declare the list with `ArrayList<String> colors = new ArrayList<>();`, add the three colors, and use a loop `for (String c : colors)` to print them using `System.out.println(c);`.
Solution available after 3 attempts