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.
Lesson 06
Keep collection element types precise so casts, raw types, and runtime class errors do not leak through the codebase.
public final class OrderSummaryIndex {
// The type says each owner can have many summaries.
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());
}
}public class OrderSummaryIndex {
public Map groupByOwner(List orders) {
Map index = new HashMap();
for (Object item : orders) {
// Raw collections push type errors to runtime casts.
OrderSummary order = (OrderSummary) item;
index.put(order.ownerId().toString(), order);
}
return index;
}
}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.
The bad version uses raw List and Map, stores only one order per owner, and pushes type mistakes to runtime.