I don't like that NonTerminal contains a NonTerminalId field, and you also have a Map<NonTerminalId, NonTerminal>. What stops the Map from connecting one NonTerminalId to a NonTerminal with a different NonTerminalId? If you want to maintain a bijection between NonTerminals and their Ids, then you should maintain that bijection in one place, as a BiMap, and then use that as the authoritative source for all ID information. You could even make this class implement BiMap...