Table of Contents
ToggleArrayLists are one of the most versatile data structures in Java, allowing dynamic storage and manipulation of data. Unlike arrays, ArrayLists can grow and shrink as needed, making them ideal for situations where the size of the collection is not predetermined. In this unit, you’ll learn how to create, traverse, and implement algorithms with ArrayLists, as well as explore their applications in searching and sorting.
Weighting: 2.5-7.5% of the test
Multiple-choice questions: 1 to 2
FRQ Potential: Likely topic for FRQ #3, focusing on creating ArrayLists and developing ArrayList algorithms.
ArrayLists are a step up from arrays, offering dynamic sizing and a host of methods to manipulate their contents. They are part of the Java Collections Framework, a library of data structures designed for different use cases. Mastering ArrayLists is key to building computational thinking and preparing for more advanced programming concepts.
Creating ArrayLists
ArrayList Methods
Traversing ArrayLists
ArrayList Algorithms
Searching: Sequential/Linear Search
Sorting: Selection Sort and Insertion Sort
An ArrayList is a dynamic data structure that stores items in an ordered list. Unlike arrays, ArrayLists do not have a fixed size, allowing elements to be added or removed as needed. This flexibility makes them highly useful in scenarios where the data size is unknown or subject to change.
Dynamic Sizing: Unlike arrays, ArrayLists can grow or shrink dynamically.
Mutability: Elements in an ArrayList can be changed after creation.
Generic Types: ArrayLists use generics to specify the type of elements they store. For example:
ArrayList<Integer> numbers = new ArrayList<>();
This ensures type safety, reducing runtime errors.
Without Initial Capacity:
ArrayList<E> list = new ArrayList<>();
With Initial Capacity:
ArrayList<E> list = new ArrayList<>(int initialCapacity);
Storing Primitive Types: Since ArrayLists only store objects, primitive types like int
or double
must be wrapped using their corresponding wrapper classes (Integer
, Double
, etc.).
The ArrayList class provides various methods to manipulate the list. Below are the most important methods for the AP CSA exam:
size(): Returns the number of elements in the ArrayList.
int count = list.size();
add(E obj): Adds an element to the end of the ArrayList.
list.add(42);
add(int index, E obj): Inserts an element at a specified index, shifting subsequent elements to the right.
list.add(2, 99);
get(int index): Retrieves the element at the specified index.
int value = list.get(0);
set(int index, E obj): Updates the element at the specified index.
list.set(1, 55);
remove(int index): Removes the element at the specified index, shifting subsequent elements to the left.
list.remove(3);
To use ArrayLists, import the class:
import java.util.ArrayList;
Traversing an ArrayList involves accessing each element in the list. You can traverse using a for loop, a while loop, or an enhanced for loop (for-each loop).
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
for (Integer number : list) {
System.out.println(number);
}
Note: Modifying the ArrayList while using a for-each loop can cause a ConcurrentModificationException.
ArrayLists are versatile and support various algorithms, including:
list.add(2, 50); // Inserts 50 at index 2
list.remove(3); // Removes the element at index 3
ArrayList to Array:
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Integer[] array = new Integer[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
Array to ArrayList:
Integer[] array = {1, 2, 3};
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(array));
Linear Search Linear search is used to find an element in an ArrayList by iterating through the list sequentially.
public int linearSearch(ArrayList<Integer> list, int target) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == target) {
return i; // Return index of the target
}
}
return -1; // Return -1 if target is not found
}
public void selectionSort(ArrayList<Integer> list) {
for (int i = 0; i < list.size(); i++) {
int minIndex = i;
for (int j = i + 1; j < list.size(); j++) {
if (list.get(j) < list.get(minIndex)) {
minIndex = j;
}
}
int temp = list.get(i);
list.set(i, list.get(minIndex));
list.set(minIndex, temp);
}
}
public void insertionSort(ArrayList<Integer> list) {
for (int i = 1; i < list.size(); i++) {
int current = list.get(i);
int j = i - 1;
while (j >= 0 && list.get(j) > current) {
list.set(j + 1, list.get(j));
j--;
}
list.set(j + 1, current);
}
}
With the increased use of data, ethical considerations around its collection, storage, and usage have grown significantly. Here are steps programmers can take to ensure ethical data handling:
Use Encryption: Protect user data with robust encryption methods.
Minimize Data Collection: Only collect data that is absolutely necessary.
Implement Strong Security Measures: Use firewalls, authentication systems, and regular audits to prevent data breaches.
Be Transparent: Clearly communicate to users what data is being collected and why.
ArrayLists are a dynamic and powerful data structure that offer flexibility and functionality far beyond static arrays. By mastering ArrayList creation, traversal, and algorithm development, you can handle complex data manipulation tasks with ease. Additionally, understanding the ethical considerations around data collection ensures you build trust with your users while protecting their privacy.
An ArrayList is a resizable array provided by Java’s java.util
package. Unlike arrays, its size can dynamically grow or shrink as elements are added or removed.
ArrayLists provide dynamic sizing, convenient methods for adding, removing, and searching elements, and are part of the Java Collections Framework, making them more versatile than arrays.
import java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
Use the add()
method:
list.add("Apple");
list.add("Banana");
Use the get()
method:
String element = list.get(0);
Use the remove()
method:
list.remove("Apple"); // Removes by value
list.remove(0); // Removes by index
Use the size()
method:
int size = list.size();
ArrayLists allow null
values:
list.add(null);
Null values are treated like any other element.
Yes, ArrayList supports generics for type safety:
ArrayList<Integer> intList = new ArrayList<>();
The default capacity is 10. When the capacity is exceeded, the ArrayList grows by 50% of its size.
Use the isEmpty()
method:
boolean empty = list.isEmpty();
Using a for
loop:
for (String item : list) {
System.out.println(item);
}
Using an iterator:
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
The ArrayList automatically resizes by increasing its capacity by 50% of its current size.
Use the toArray()
method:
String[] array = list.toArray(new String[0]);
Use the Collections.sort()
method:
Collections.sort(list);
Use the contains()
method:
boolean found = list.contains("Apple");
Use the set()
method:
list.set(0, "Orange");
Use the clear()
method:
list.clear();
Use the indexOf()
method:
int index = list.indexOf("Apple");
Yes, ArrayLists allow duplicate elements.
ArrayList: Fast random access, slower insertions/removals.
LinkedList: Slower random access, faster insertions/removals.
Use Arrays.asList()
:
String[] array = {"Apple", "Banana"};
ArrayList<String> list = new ArrayList<>(Arrays.asList(array));
ArrayList: Not synchronized, better performance.
Vector: Synchronized, slower performance.
Use a Set
to filter duplicates:
list = new ArrayList<>(new HashSet<>(list));
An IndexOutOfBoundsException
is thrown.
Use Collections.reverse()
:
Collections.reverse(list);
Yes, use Collections.synchronizedList()
:
List<String> synchronizedList = Collections.synchronizedList(list);
Use the clone()
method:
ArrayList<String> clonedList = (ArrayList<String>) list.clone();
Use the equals()
method:
boolean isEqual = list1.equals(list2);
Use Collections.shuffle()
:
Collections.shuffle(list);
Use Collections.sort()
with a comparator:
Collections.sort(list, Collections.reverseOrder());
Yes, you can create nested ArrayLists:
ArrayList<ArrayList<Integer>> multiList = new ArrayList<>();
Slower than arrays for primitive types.
Not thread-safe unless synchronized.
Example using filter
:
list.stream().filter(s -> s.startsWith("A")).forEach(System.out::println);
Use toString()
:
String str = list.toString();
Yes, ArrayLists are serializable if the elements are also serializable.
Use removeIf()
:
list.removeIf(s -> s.startsWith("A"));
Access: O(1)
Insert/Remove at End: O(1)
Insert/Remove at Index: O(n)
for (int i = list.size() - 1; i >= 0; i--) {
System.out.println(list.get(i));
}
Use Collections.unmodifiableList()
:
List<String> immutableList = Collections.unmodifiableList(list);
ArrayList<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
isEmpty()
: Returns true
if the list is empty.
size()
: Returns the number of elements in the list.
String lastElement = list.get(list.size() - 1);
Yes, nested ArrayLists are possible and useful for hierarchical data:
ArrayList<ArrayList<Integer>> nestedList = new ArrayList<>();
list.forEach(item -> System.out.println(item));
Reduces the capacity of the ArrayList to its current size:
list.trimToSize();
Use synchronized collections or CopyOnWriteArrayList
:
List<String> safeList = Collections.synchronizedList(list);
Use addAll()
:
list.addAll(anotherList);
clear()
: Removes all elements.
removeAll()
: Removes only elements matching another collection.
Use Collections.frequency()
:
int freq = Collections.frequency(list, "Apple");