Arrays & Lists
What Are Arrays and Lists?
Arrays and lists store multiple values under a single variable name.
Arrays have fixed sizes, while lists (or ArrayLists in Java) are resizable.
Comparison of Arrays and Lists
| Feature | Arrays | Lists |
|---|---|---|
| Size | Fixed at creation. | Dynamic, can grow or shrink. |
| Memory Usage | Less memory overhead. | More overhead due to dynamic resizing. |
| Operations | Efficient for indexed access. | Better for frequent insertions/removals. |
| Examples | 1D and 2D arrays. | ArrayLists (Java), Lists (Python). |
Lists vs Arrays - When and Why
Lists are dynamic collections: they grow and shrink at runtime, and they’re ideal when the number of items
isn’t known in advance or changes frequently. Arrays (in Java) are fixed-size: you decide their length
up front; you can change elements, but not the capacity. In Python, the everyday sequence is a list (dynamic);
Python does not have a built-in fixed-size array like Java. The standard library does include array.array
(typed, one-dimensional) and many projects use NumPy’s ndarray for numerical work, but neither are developed here.
1D Lists (Dynamic Collections)
Overview
Use a 1D list when your collection’s size may change or you frequently add/remove items. Access is 0-based in both languages. The examples below demonstrate initialisation, adding, removing (by value and by index), and multiple traversal styles.
Sample A: Initialise a list, add items, remove by value and by index, then traverse with an index-based loop.
# Initialise
fruits = ["apple", "banana", "cherry"]
# Add
fruits.append("date") # ["apple", "banana", "cherry", "date"]
# Remove by value (first match)
fruits.remove("banana") # ["apple", "cherry", "date"]
# Remove by index
removed = fruits.pop(1) # removes "cherry" → ["apple", "date"]
# Traversal: loop + index
for i in range(len(fruits)):
print(i, fruits[i])
Sample B: Shorter example showing index removal and traversal via enumerate (index + value).
# Initialise and mutate
nums = [10, 20, 30]
nums.append(40) # [10, 20, 30, 40]
first = nums.pop(0) # remove by index → first = 10, nums = [20, 30, 40]
# Traversal: enumerate (Python "enumerator")
for i, value in enumerate(nums):
print(f"index={i}, value={value}")
Sample A: Initialise an ArrayList<String>, add items, remove by value and by index, then traverse with an index-based loop.
import java.util.ArrayList;
public class ListIndexLoop {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
// Initialise via adds
fruits.add("apple");
fruits.add("banana");
fruits.add("cherry");
// Add
fruits.add("date");
// Remove by value (first match)
fruits.remove("banana");
// Remove by index
String removed = fruits.remove(1); // removes "cherry"
// Traversal: loop + index
for (int i = 0; i < fruits.size(); i++) {
System.out.println(i + " -> " + fruits.get(i));
}
}
}
Sample B: Show both an enhanced for-loop and an explicit Iterator<E>. Also contrasts removal by value vs index for Integer.
import java.util.ArrayList;
import java.util.Iterator;
public class ListIteratorDemo {
public static void main(String[] args) {
ArrayList<Integer> nums = new ArrayList<>();
nums.add(10);
nums.add(20);
nums.add(30);
nums.add(20);
// Remove by value vs by index (note Integer.valueOf!)
nums.remove(Integer.valueOf(20)); // remove first 20 by value
nums.remove(1); // remove element at index 1
// Traversal: enhanced for-loop
for (int n : nums) {
System.out.println("for-each: " + n);
}
// Traversal: Iterator
Iterator<Integer> it = nums.iterator();
while (it.hasNext()) {
int n = it.next();
System.out.println("iterator: " + n);
}
}
}
2D Lists (Lists of Lists)
Overview
A 2D list is a list whose elements are themselves lists (rows). This supports “jagged” structures where rows can have different lengths. Use 2D lists when your grid grows or shrinks by rows/columns at runtime. Examples show adding/removing within rows and traversing with both index-based loops and idiomatic enumerations/iterators.
Sample A: Initialise a 2D list, add within a row and add a new row, remove by value and by index, then traverse with nested index loops.
# Initialise (rows)
matrix = [
[1, 2, 3],
[4, 5, 6]
]
# Add within a row
matrix[0].append(99) # first row now [1, 2, 3, 99]
# Add a new row
matrix.append([7, 8, 9])
# Remove by value in a row
matrix[1].remove(5) # row 1 becomes [4, 6]
# Remove by index in a row
popped = matrix[2].pop(0) # removes 7 from third row
# Traversal: nested loop + index
for r in range(len(matrix)):
for c in range(len(matrix[r])):
print(f"[{r}][{c}] = {matrix[r][c]}")
Sample B: Enumerate rows and columns to get both indices and values cleanly.
# Re-initialise for clarity
grid = [[11, 12], [31, 43], [15, 26]]
# Traversal: enumerate rows and columns
for r_idx, row in enumerate(grid):
for c_idx, val in enumerate(row):
print(f"r={r_idx}, c={c_idx}, val={val}")
Sample A: 2D dynamic structure with ArrayList<ArrayList<Integer>>; add rows/elements, remove by value vs index, traverse with nested index loops.
import java.util.ArrayList;
public class List2DIndexLoop {
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> matrix = new ArrayList<>();
// Initialise: add two rows
ArrayList<Integer> row0 = new ArrayList<>();
row0.add(1); row0.add(2); row0.add(3);
matrix.add(row0);
ArrayList<Integer> row1 = new ArrayList<>();
row1.add(4); row1.add(5); row1.add(6);
matrix.add(row1);
// Add within a row and add a new row
matrix.get(0).add(99);
ArrayList<Integer> row2 = new ArrayList<>();
row2.add(7); row2.add(8); row2.add(9);
matrix.add(row2);
// Remove by value vs by index in a row (Integers!)
matrix.get(1).remove(Integer.valueOf(5)); // remove value 5 from row1
matrix.get(2).remove(0); // remove element at index 0 of row2
// Traversal: nested loop + index
for (int r = 0; r < matrix.size(); r++) {
for (int c = 0; c < matrix.get(r).size(); c++) {
System.out.println("[" + r + "][" + c + "] = " + matrix.get(r).get(c));
}
}
}
}
Sample B: Enhanced for over rows plus an Iterator over each inner row.
import java.util.ArrayList;
import java.util.Iterator;
public class List2DIteratorDemo {
public static void main(String[] args) {
ArrayList<ArrayList<String>> names = new ArrayList<>();
ArrayList<String> a = new ArrayList<>(); a.add("Ann"); a.add("Ava");
ArrayList<String> b = new ArrayList<>(); b.add("Ben"); b.add("Bea");
names.add(a);
names.add(b);
// Traversal: enhanced for rows, Iterator for columns
for (ArrayList<String> row : names) {
Iterator<String> it = row.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println("name=" + s);
}
}
}
}
Arrays (Java) - 1D & 2D
Overview
Java arrays are fixed-size. You can mutate elements but cannot add or remove capacity; to change size, create a new array
and copy. This predictability suits tight loops and stable shapes. In Python, the common sequence is a list (dynamic).
Python’s stdlib has array.array (typed, 1D) and the scientific ecosystem uses NumPy ndarray, but those are beyond this page.
1D Array: Initialise via literal and with a fixed length; mutate elements; traverse with index and enhanced for-loop.
public class Array1D {
public static void main(String[] args) {
// Initialise
int[] nums = {10, 20, 30}; // fixed size = 3
int[] more = new int[4]; // defaults to 0
more[0] = 7; more[1] = 8;
// Mutate elements (capacity cannot change)
nums[1] = 99;
// Traversal: loop + index
for (int i = 0; i < nums.length; i++) {
System.out.println(i + " -> " + nums[i]);
}
// Traversal: enhanced for-loop
for (int n : nums) {
System.out.println("for-each: " + n);
}
}
}
2D Array: Rectangular matrix, mutate a cell, traverse with nested index loops and nested enhanced for-loops.
public class Array2D {
public static void main(String[] args) {
// Initialise (rectangular)
int[][] grid = {
{1, 2, 3},
{4, 5, 6}
};
// Mutate an element
grid[1][2] = 99;
// Traversal: nested loop + index
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
System.out.println("[" + r + "][" + c + "] = " + grid[r][c]);
}
}
// Traversal: nested enhanced for-loops
for (int[] row : grid) {
for (int val : row) {
System.out.println("val=" + val);
}
}
}
}
Python does not provide a built-in fixed-size array like Java. The everyday sequence type is list, which
is dynamic (grows and shrinks). The standard library includes array.array (typed, one-dimensional) and the scientific
stack uses NumPy’s ndarray for high-performance numerical arrays, but these are beyond the scope of this page.
For all Python examples here, prefer lists.
Summary of Operations
Python Operations
numbers[index]andmatrix[row][col]: 0‑based access of list and 2D list elements..append(value): add an element to the end of a list..remove(value): remove the first matching value from the list, shifting subsequent elements left..pop(index): remove the value at index from the list, shifting subsequent elements left.forloops: iterate over 1D and nested lists for processing or modification.
Java Operations
array[index]andmatrix[row][col]: 0‑based access of array and 2D array elements..add(value)(ArrayList): append an element to a dynamic array..remove(Integer.valueOf(2)): in anArrayListcontaining Integers, remove the first matching value (2) from the list, shifting subsequent elements left..remove("egg"): remove the first matchingStringvalue ("egg") from the list, shifting subsequent elements left..remove(2): delete element by index, (2) shifting subsequent elements left.forloops: iterate over 1D and nested lists for processing or modification.
Advantages and Disadvantages
- Arrays:
- ✔ Faster access via indexing.
- ✔ Lower memory overhead.
- ✖ Fixed size, cannot resize.
- Lists (ArrayLists in Java):
- ✔ Dynamic resizing for flexibility.
- ✔ Easier insertion and deletion.
- ✖ Higher memory overhead.
Key Takeaways
- 1D and 2D arrays are fixed-size structures ideal for indexed access.
- Lists (Python) and ArrayLists (Java) resize dynamically and simplify element management.
- Choose between arrays and lists based on speed, memory usage, and flexibility.