Collections and Generics
The Collections Framework
| Interface | Implementations | Characteristics |
|---|---|---|
List | ArrayList, LinkedList | Ordered, allows duplicates |
Set | HashSet, LinkedHashSet, TreeSet | No duplicates |
Map | HashMap, LinkedHashMap, TreeMap | Key-value pairs |
Queue / Deque | ArrayDeque, PriorityQueue, LinkedList | FIFO / double-ended / priority |
import java.util.*;
List<String> names = new ArrayList<>();
names.add("Asha");
names.add("Ravi");
Collections.sort(names);
Set<Integer> unique = new HashSet<>(List.of(1, 2, 2, 3)); // [1, 2, 3]
Map<String, Integer> marks = new HashMap<>();
marks.put("Asha", 91);
marks.merge("Asha", 5, Integer::sum); // 96
for (Map.Entry<String, Integer> e : marks.entrySet()) {
System.out.println(e.getKey() + " -> " + e.getValue());
}
Complexity cheat sheet
| Structure | Access / lookup | Insert | Notes |
|---|---|---|---|
ArrayList | O(1) by index | O(1) amortised at end | Dynamic array |
LinkedList | O(n) | O(1) at known node | Rarely the best choice |
HashMap / HashSet | O(1) average | O(1) average | Unordered |
TreeMap / TreeSet | O(log n) | O(log n) | Sorted |
PriorityQueue | O(1) peek | O(log n) | Binary heap |
Generics
Generics provide compile-time type safety and remove casts.
public class Box<T> {
private T value;
public Box(T value) { this.value = value; }
public T get() { return value; }
}
Box<String> b = new Box<>("hello");
String s = b.get(); // no cast needed
static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
Streams
import java.util.stream.*;
List<Integer> nums = List.of(1, 2, 3, 4, 5, 6);
int sumOfSquaresOfEvens = nums.stream()
.filter(n -> n % 2 == 0)
.mapToInt(n -> n * n)
.sum(); // 4 + 16 + 36 = 56
List<String> upper = Stream.of("a", "b").map(String::toUpperCase).collect(Collectors.toList());
TIP
Use the interface type on the left (List<String> xs = new ArrayList<>()) so the implementation can change without touching the rest of the code.
Loading Comments...