Nested collections
Build a map of lists, and know when a copy still shares the collections inside it.
Open this lesson in the learning hubKey points
- A map of lists is the everyday grouping structure: one key, many values, no separate class needed.
- Fill it with
map.computeIfAbsent(key, k -> new ArrayList<>()).add(value)— no null check anywhere. - Read it with
getOrDefault(key, List.of())so a missing key gives an empty list, notnull. - Counters nest the same way:
computeIfAbsentfor the inner map, thenmergeon it. new HashMap<>(other)is a shallow copy. The inner lists are shared, so edits show up in both maps.- For a real copy, rebuild each inner collection. Or store immutable inner lists so nobody can edit them at all.
Example
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<String, List<String>> byTeam = new LinkedHashMap<>();
String[][] rows = {{"eng", "ana"}, {"ops", "bo"}, {"eng", "cy"}, {"ops", "di"}};
for (String[] r : rows) {
byTeam.computeIfAbsent(r[0], k -> new ArrayList<>()).add(r[1]);
}
System.out.println("grouped : " + byTeam);
System.out.println("eng members : " + byTeam.getOrDefault("eng", List.of()));
System.out.println("qa members : " + byTeam.getOrDefault("qa", List.of()) + " (no null check needed)");
Map<String, Map<String, Integer>> nested = new LinkedHashMap<>();
nested.computeIfAbsent("eu", k -> new LinkedHashMap<>()).merge("orders", 2, Integer::sum);
nested.computeIfAbsent("eu", k -> new LinkedHashMap<>()).merge("orders", 3, Integer::sum);
nested.computeIfAbsent("us", k -> new LinkedHashMap<>()).merge("orders", 1, Integer::sum);
System.out.println("nested counters : " + nested);
Map<String, List<String>> shallow = new LinkedHashMap<>(byTeam);
shallow.get("eng").add("eve");
System.out.println("shallow copy add : " + byTeam.get("eng") + " (original changed too)");
Map<String, List<String>> deep = new LinkedHashMap<>();
byTeam.forEach((k, v) -> deep.put(k, new ArrayList<>(v)));
deep.get("eng").add("fay");
System.out.println("deep copy add : " + deep.get("eng"));
System.out.println("original after it : " + byTeam.get("eng") + " (untouched)");
}
}
computeIfAbsent builds the inner collection; only a rebuilt copy stops two maps sharing it.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Collections course, and every lesson in it is listed on the Collections contents page.