package ch.claude_martin.foo; import java.util.*; public class SomeClass implements Comparable { private static Comparator COMPARATOR = Comparator.comparing(SomeClass::getCode).thenComparing(SomeClass::getName); private final String name, code; private final NavigableSet children = new TreeSet(); private final SomeClass parent; // doesn't have to be public. only factory needs access. SomeClass(SomeClass parent, String name, String code) { this.parent = parent; this.name = name; this.code = code; } // Creates a root SomeClass(String name, String code) { this(null, name, code); } // doesn't have to be public. only factory needs access. void addChild(SomeClass child) { this.children.add(child); } public NavigableSet getChildren() { return new TreeSet<>(this.children); // return defensive copy } public Optional getParent() { return Optional.ofNullable(this.parent); } public String getName() { return name; } public String getCode() { return code; } @Override public int compareTo(SomeClass o) { return COMPARATOR.compare(this, o); } }