Search code examples
javaenumsspecial-charactersjava-6

Enums with special characters : How to?


I currently work on a parser. I walk a tree, most of it being quite determinist (I have a finite number of values I can find).

Usually in these cases, I create an enum with the name of the value I expect to find, like this :

public enum myElements{
    like, 
    not_like,// "not like" is transformed in not_like by parser
    exists;
}   

in this case, I can check whether a string belongs to the enum this way :

String my_string;
myElements.valueOf(my_string);

The thing is that currently I work with special characters ({">", "<", "<>", ...) It is not possible to create enum value with special characters.

What I would like is to associate an enum with those special characters elements, something like

public enum myElements{
    greather_than(">"), 
    smaller_than("<")
}

and continue using something as straightforward as:

myElements.valueOf(my_string);

For the moments I use enums everywhere but for these elements, where I use of table. I'd like to harmonize this

BTW, I work with Java6, due to some dependancies.

An idea is welcome, Thanks !

EDIT :

Here is an example of the current table version I use :

public static String[] compElements = {">", "<", "<>", "=", "<=", ">="};

with the equivalent for the valueOf :

Arrays.asList(compElements).contains(my_string);

Solution

  • It sounds like you just want your enum to store a map of all the "flexible" names, mapping the name to the enum value. You wouldn't be able to use valueOf, but you could easily write your own static method to return the relevant mapped value. Create the map in a static initializer block. (Don't forget that when the constructors are called automatically, static initializers will not have executed.)

    Sample code:

    public enum Foo {
      // Idiomatic Java names. You could ignore those if you really want,
      // and overload the constructor to have a parameterless one which calls
      // name() if you really want.
      FIRST("first"),
      SECOND("second"),
      WITH_SPACE("with space");
    
      private static final Map<String, Foo> nameToValueMap;
    
      static {
        // Really I'd use an immutable map from Guava...
        nameToValueMap = new HashMap<String, Foo>();
        for (Foo foo : EnumSet.allOf(Foo.class)) {
          nameToValueMap.put(foo.friendlyName, foo);
        }
      }
    
      private final String friendlyName;
    
      private Foo(String friendlyName) {
        this.friendlyName = friendlyName;
      }
    
      public String getFriendlyName() {
        return friendlyName;
      }
    
      public static Foo fromFriendlyName(String friendlyName) {
        return nameToValueMap.get(friendlyName);
      }
    }