Java

Lesson 06

Generics and collection types

Keep collection element types precise so casts, raw types, and runtime class errors do not leak through the codebase.

Good Code

src/main/java/dev/review/orders/OrderSummaryIndex.java
public final class OrderSummaryIndex {
    public Map<UserId, List<OrderSummary>> groupByOwner(List<OrderSummary> orders) {
        return orders.stream()
            .collect(Collectors.groupingBy(OrderSummary::ownerId));
    }

    public List<OrderSummary> summariesFor(
        Map<UserId, List<OrderSummary>> index,
        UserId ownerId
    ) {
        return index.getOrDefault(ownerId, List.of());
    }
}

Bad Code

src/main/java/OrderSummaryIndex.java
public class OrderSummaryIndex {
    public Map groupByOwner(List orders) {
        Map index = new HashMap();
        for (Object item : orders) {
            OrderSummary order = (OrderSummary) item;
            index.put(order.ownerId().toString(), order);
        }
        return index;
    }
}

Review Notes

What to review

Good Code

The good version names both the key and value types. Reviewers can see that one owner may have many summaries, and callers do not need casts.

Bad Code

The bad version uses raw List and Map, stores only one order per owner, and pushes type mistakes to runtime.

Takeaways

  • A Java collection type should tell reviewers what it contains and what key shape it expects.