Similarly, you can add more fields to an enum and simply provide accessor methods to retrieve them.

For example you could change it to have an extra field indicating an output directory to write specific types of data to, and a getter method to return that directory.

public enum Foo {
        private final String f;
        private static Map<String, Foo> foos;
        private Foo(final String f) {
            this.f = f;
  , this);
        private static void foo(String f, Foo foo) {
            if (foos == null) {
                foos = new HashMap<String, Foo>();
            foos.put(f, foo);
        public String toString() {
            return f;
        public static Foo getFoo(final String f) {
            return foos.get(f);


Why have a whole HashMap implemetation just to find enum values from their "f" String. Since enums usually have a small number of values you could simply search Foo.values() for a match (with the option of a case-insensitive search if you want)

And why the extra code for lazy initialisation of foos when the constructors (and therefore foo(f, this)) will be executed when the enum is loaded anyway?

could work. This is the way I've been doing it since enums were introduced, based on experimenting with some (at the time) colleagues.
May well be there are more efficient ways to do it, remember at the time it was all brand new and just figuring out this worked was helping us a lot getting things done.