CHAPTER 03 · INTERMEDIATE4 min read

Lists, HashMaps, and Type-Safe Generics

Master ArrayList, LinkedList, HashMap internal hashing mechanics, equals/hashCode contracts, and bounded generics.

OpenJDK 21+ (LTS)Free to readModule 2 of 3
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Compare ArrayList and LinkedList memory layouts and evaluate Big-O algorithmic tradeoffs.
  • Explain HashMap bucket indexing, load factors, hash collisions, and the equals/hashCode contract.
  • Implement type-safe generic classes and methods with upper and lower wildcards.

01ArrayList vs LinkedList: Memory and Algorithmic Tradeoffs

The Java Collections Framework provides two ubiquitous List implementations: ArrayList and LinkedList. While both implement the List interface, their underlying memory layouts differ fundamentally, leading to vastly different performance characteristics.

ArrayList is backed by a dynamically resizing contiguous array. This grants lightning-fast O(1) random access by index via direct memory pointer arithmetic. In contrast, LinkedList consists of doubly linked node objects scattered across the heap. Accessing an element by index in a LinkedList requires traversing node pointers sequentially from either head or tail, incurring O(N) time and causing CPU cache line misses. Consequently, ArrayList is virtually always the superior choice in modern computing.

example.js☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02HashMap Internals: Hash Codes and Collision Resolution

HashMap is the cornerstone of associative data storage in Java, providing average O(1) time complexity for put and get operations. When a key is inserted into a HashMap, Java invokes key.hashCode() and applies a bit-spreading function to compute a bucket index within an internal array of Node objects.

If two distinct keys produce the same bucket index (a hash collision), Java chains the nodes in that bucket. In Java 8 and beyond, when a bucket contains more than 8 elements and the total map capacity exceeds 64, the linked bucket automatically transforms into a balanced Red-Black Tree. This limits worst-case search time to O(log N) instead of catastrophic O(N) degradation.

example.js☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03The Critical equals() and hashCode() Contract

For a custom class to serve safely as a key in a HashMap or HashSet, it must strictly satisfy the equals and hashCode contract defined in java.lang.Object.

The contract specifies two unbreakable rules: First, if two objects are equal according to their equals(Object) method, calling hashCode() on each must produce the exact same integer value. Second, if hashCode() changes while an object is stored as a key in a map, the key becomes permanently lost and unretrievable. Always compute hash codes using immutable fields exclusively.

example.js☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Type Safety with Java Generics and Wildcards

Generics enable types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. Generics eliminate manual type casting and detect type mismatches at compile time rather than crashing in production with ClassCastException.

When designing extensible generic methods, the PECS principle (Producer Extends, Consumer Super) dictates wildcard usage. Use <? extends T> when reading data from a collection, and <? super T> when writing data into a collection.

In conclusion, adopting these engineering practices transforms prototype scripts into resilient, production-ready modules. Continual testing against real-world edge cases, monitoring telemetry metrics, and documenting architectural decisions ensures the long-term maintainability and performance of the codebase as system demands expand.

example.js☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
LET IT CLICK

The ideas worth keeping.

  • Prefer ArrayList over LinkedList for almost all list storage due to contiguous memory and CPU cache locality.
  • Always override hashCode() whenever you override equals() using immutable fields.
  • Apply the PECS principle (Producer Extends, Consumer Super) when writing flexible generic APIs.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Frequency Map Counter

Write a static method countWordFrequencies(List<String> words) that returns a Map<String, Integer> with word occurrence counts.

your_turn_1.java☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.javaJava
public static Map<String, Integer> countWordFrequencies(List<String> words) {    Map<String, Integer> counts = new HashMap<>();    for (String w : words) {        counts.merge(w, 1, Integer::sum);    }    return counts;}

Map.merge() (introduced in Java 8) provides an atomic, clean way to increment counter tallies in a single line.

02

Generic Swap Utility

Write a generic method <T> void swap(T[] array, int i, int j) that swaps elements at indices i and j in an array.

your_turn_2.java☕Java
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.javaJava
public static <T> void swap(T[] array, int i, int j) {    T temp = array[i];    array[i] = array[j];    array[j] = temp;}

Generic type parameters allow a single swap method to operate on arrays of any reference type safely.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01What occurs if two objects evaluate as equal via equals(), but have different hashCode() values in a HashMap?
02Why is ArrayList typically faster than LinkedList for sequential traversal on modern CPUs?
03What does the PECS mnemonic stand for when working with Java generic wildcards?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Frequency Map Counter

Write a static method countWordFrequencies(List<String> words) that returns a Map<String, Integer> with word occurrence counts.

EXPECTED OUTPUT
Build successful. (Java 15)
[Process exited normally]
challenge.pyPython 3
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this chapter, when you want a second angle or the full details.

One chapter closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock chapter completion.