Arrays and Lists in Java
Work with fixed-size arrays and dynamic lists — create and traverse arrays, use ArrayList and LinkedList, understand the List interface, and compare trade-offs.
Array Creation
A Java **array** is a fixed-size, ordered collection of elements of the same type. Once created, its length cannot change. Use `ArrayList` when you need a resizable list.
1. Array Literal
Declare and initialize an array in one line using the `{ }` initializer syntax.
2. Array Constructor (new)
Create an array with `new Type[size]` when you know the size but not the values yet.
Array Fundamentals
Arrays are fixed-size, so "removal" means shifting elements or using `ArrayList`. Use `ArrayList` for dynamic insertion and removal.
1. Getting Size
Arrays use `.length`; `ArrayList` uses `.size()`.
2. Accessing Element at Index
Arrays use `arr[i]`; `ArrayList` uses `.get(i)`. Both are zero-indexed.
3. Updating Element at Index
Arrays use `arr[i] = value`; `ArrayList` uses `.set(i, value)`.
4. Removing Element at Index
`ArrayList` supports `.remove(index)`. Arrays are fixed — use `ArrayList` when removal is needed.
Traversing a List
Java provides multiple ways to traverse arrays and lists: classic `for`, enhanced `for-each`, `forEach()` with lambda, and `Iterator`.
1. Regular for Loop
Use a classic `for` loop when you need the index during traversal.
2. for-each Loop
Use enhanced `for-each` when you only need the value, not the index.
3. forEach with Lambda
Use `.forEach()` for a functional-style traversal on any `Iterable`.
Searching, Joining & Comparing
Java provides `contains()`, `indexOf()`, `Arrays.equals()`, and `String.join()` for common search and comparison operations.
1. Check if an Element Exists
`List.contains()` checks by value. For arrays, use `Arrays.asList().contains()` or a stream.
2. Find Element Index
`indexOf()` returns the first index of a value, or `-1` if not found.
3. Find Element Index from Last
`lastIndexOf()` returns the last index of a value.
4. Joining Elements
Use `String.join()` or streams `.collect(Collectors.joining())` to join list elements into a string.
5. Comparing Arrays by Contents
Use `Arrays.equals()` to compare arrays by value. `==` compares references, not contents.
Insertion & Removal
`ArrayList` supports all insertion and removal operations. Use `add()`, `add(index, value)`, `remove()`, and `addFirst()`/`addLast()` (via `LinkedList` or `ArrayDeque`).
1. Insert / Remove from End
`add()` appends to the end; `remove(size-1)` or `removeLast()` removes from the end.
2. Insert / Remove from Start
`add(0, value)` inserts at the beginning; `remove(0)` removes the first element.
3. Insert & Remove at Specific Index
`add(index, value)` inserts at a position; `remove(index)` removes at a position.
Advanced Array & List Operations
Java's `Collections` and `Arrays` utility classes provide powerful methods for sorting, reversing, and manipulating arrays and lists.
1. Reverse
`Collections.reverse()` reverses an `ArrayList` in-place. For arrays, use a loop or `Collections.reverse(Arrays.asList(arr))`.
2. Sort
`Collections.sort()` sorts a list in natural order. Use a `Comparator` for custom ordering.
3. Shuffle
`Collections.shuffle()` randomly reorders list elements.
4. Multi-dimensional Array
Java supports 2D (and higher) arrays using `Type[][]`.
5. Traversing Multi-dimensional Arrays
Use nested `for` or `for-each` loops to traverse a 2D array.
6. Concatenating Lists
`addAll()` appends all elements of one list to another. For arrays, use `Stream.concat()`.
7. Flattening Nested Lists
Use `flatMap()` on streams to flatten a `List<List<T>>` into a single `List<T>`.
8. Removing Duplicates
Use `stream().distinct()` to remove duplicate elements, or convert to a `Set`.
9. Shallow & Deep Clone
Use `new ArrayList<>(original)` for a shallow copy. For deep copy of objects, manually clone each element.
Higher Order Functions
Java's **Stream API** (Java 8+) provides built-in higher-order methods on collections. Call `.stream()` on any `List` or array, then chain operations.
1. map()
Transform each element using `.map()`. Returns a new stream with the transformed values.
2. filter()
Keep only elements that match a condition using `.filter()`.
3. reduce()
Combine all elements into a single value using `.reduce()`.
4. forEach()
Run an action on each element using `.forEach()`. Does not return a value.
5. find() — findFirst()
Find the first matching element using `.filter().findFirst()`. Returns an `Optional`.
6. findIndex()
Java has no direct `findIndex()` — use `IntStream.range()` with a predicate, or `indexOf()` for equality.
7. anyMatch() & allMatch() & noneMatch()
Check conditions across all elements — equivalent to `some()`, `every()` in JavaScript.
8. Chaining Operations
Chain multiple stream operations — filter, map, sort, and collect in one pipeline.
ArrayList vs LinkedList
Both implement the `List` interface. `ArrayList` is backed by a resizable array — fast for random access. `LinkedList` is backed by a doubly-linked list — fast for insertions and deletions at the front/middle.
1. LinkedList Basics
`LinkedList` implements both `List` and `Deque` — it supports queue and stack operations in addition to list operations.
2. Performance Comparison
Choose `ArrayList` for most use cases. Use `LinkedList` only when you do frequent insertions/deletions at the front.