Hierarchical structures with Java Enums
I love Enums. There are a lot of use cases, where they become really handy. Especially since I have learned that you can override methods in enums…
Some days ago Alexander Radzin came up with another nice idea: He created a hierarchical structure using enums. The idea is very simple: Just add a reference to the parent to your enum.
While the idea is really nice, the implementation seems to be a little bit too complicated. I think using reflection is not a very nice thing at all. Therefore I have modified his implementation.
And this is the idea. That idea has a lot of potential – I am sure I will find a lot of nice use cases…
public enum OsType {
OS(null),
Windows(OS),
WindowsNT(Windows),
WindowsNTWorkstation(WindowsNT),
WindowsNTServer(WindowsNT),
Windows2000(Windows),
Windows2000Server(Windows2000),
Windows2000Workstation(Windows2000),
WindowsXp(Windows),
WindowsVista(Windows),
Windows7(Windows),
Windows95(Windows),
Windows98(Windows),
Unix(OS) {
@Override
public boolean supportsXWindowSystem() {
return true;
}
},
Linux(Unix),
AIX(Unix),
HpUx(Unix),
SunOs(Unix),
;
private final OsType parent;
private final List children = new ArrayList();
private final List allChildren = new ArrayList();
OsType( OsType parent ) {
this.parent = parent;
if ( parent != null ) {
parent.addChild( this );
}
}
public OsType parent() {
return parent;
}
public boolean is( OsType other ) {
if ( other == null ) {
return false;
}
for ( OsType osType = this; osType != null; osType = osType.parent() ) {
if ( other == osType ) {
return true;
}
}
return false;
}
public List children() {
return Collections.unmodifiableList( children );
}
public List allChildren() {
return Collections.unmodifiableList( allChildren );
}
private void addChild( OsType child ) {
this.children.add( child );
List greatChildren = new ArrayList();
greatChildren.add( child );
greatChildren.addAll( child.allChildren() );
OsType currentAncestor = this;
while ( currentAncestor != null ) {
currentAncestor.allChildren.addAll( greatChildren );
currentAncestor = currentAncestor.parent;
}
}
public boolean supportsXWindowSystem() {
if ( parent == null ) {
return false;
}
return parent.supportsXWindowSystem();
}
}
October 9th, 2010 at 19:13
You suggested very good improvement of the idea. Thank you very much for your interest. I am absolutely agree that reflection should be used only when there is no other way to solve the problem, so your approach is definitely better than mine.
September 11th, 2012 at 01:20
I know it’s very far but please consider this in order to remove supportsXWindowSystem() override on UNIX and replace it by
…
Unix(OS,true),
…
then you add another combo field+constructor
…
private Boolean supportX = null;
OsType(OsType parent, Boolean supportX)
{
this(parent);
this.supportX = supportX;
}
…
then you modify the last return in supportsXWindowSystem method with :
if (supportX == null)
{
return parent.supportsXWindowSystem();
}
else
{
return supportX;
}