You obviously want to model a tree. This tree is not necessarily associated with a TreeMap explicitly. And admittedly, I donβt see how TreeMap can help represent the whole structure (although it can be used in separate nodes of the tree).
You can create a class like this
class Node { private final String name; private final Map<String, Node> children; private final CustomObject customObject; Node(String name, CustomObject customObject) { this.name = name; this.children = new LinkedHashMap<String, Node>(); this.customObject = customObject; } String getName() { return name; } void addChild(Node child) { children.put(child.getName(), child); } void removeChild(String name) { children.remove(name); } Node getChild(String name) { return children.get(name); } Set<Node> getChildren() { return Collections.unmodifiableSet( new LinkedHashSet<Node>(children.values())); }
(quick sketch only)
Then you could build a hierarchy like this
Node root = new Node("", null); Node a1 = new Node("A1", null); Node a2 = new Node("A2", null); root.addChild(a1); root.addChild(a2); Node a11 = new Node("A11", x); Node a12 = new Node("A12", y); a1.addChild(a11); a1.addChild(a12);
This would already allow you to move around the hierarchy, and maintaining relationships would be fairly easy.
I did not quite understand what you said about "uniqueness." In any case, in such a tree, each node is uniquely identified by its path. You can even create a utility method, for example
CustomObject c = root.find("A", "A1", "A11");
for quick access to an object through a sequence of node names.
Aside: as already indicated, deeply nested cards (or lists or sets) are doubtful. But no matter what, you should always use interfaces, for example, in
Map<String, Map<String, CustomObject>> maps;
This may be normal for some use cases, but depending on what you want to model (and especially when there is another layer), it may already be inconvenient.