简体   繁体   中英

Best way to Enumerate Java

I'm wondering about a good method to enumerate in Java.

I've wondered this for a long time, and typically I come up with something that includes several independent enums and functions, and some defines and such.

But basically, I want to define unique number keys for various types of enumerations, with sub enumerations.

For example, I'm trying to implement a language with various keywords and symbols, with a number corresponding to that element, in the parenthesis. Like element(id).

Keywords: program(1), call(2), if(3), else(4), elsif(5), ... Symbols ';'(6), ','(7), '='(8), '+'(9), ... Operations: and(10), or(11), ...

What would be the best way to accomplish this?

I hope my posting was clear. But basically I'm trying to create categories of element types, and then the element definitions within them, that have an associated numeric value.

The purpose of this would be so that I could, check an input string to return the integer value if it identified substrings in the input as elements in the "dictionary" above.

Thanks in advance!

You shouldn't care about the numeric values of the enums themselves and you shouldn't depend on them. The reason being that, if in the future you or someone else decides to add a new enum to the middle of your list of enums, all your numeric values are now invalid and you'll have to go through the code and change them. Hence it's better to depend on the actual enum rather than the enum's numeric value.

If you're trying to "group" enums together (if I understand your question correctly), you could use something like a marker interface. So for example you could have:

public interface Operators {
}

public enum BooleanOperators implements Operators {    
   AND, OR, NOT, XOR
}

public enum ArithmeticOperators implements Operators {
   ADD, SUBTRACT, MULTIPLY, DIVIDE
}

Then instead of having two methods, one that would accept enums of type BooleanOperators and another that would accept types of ArithmeticOperators , you can have a single method that accepts type Operators :

public void doSomethingWithOperators(Operators operators) {
    ....
}

If you want to tie explicit values to your enums, there is a safe way to do it:

public interface Operators {
    int getCode();
}

public enum BooleanOperators implements Operators {

   private int code;

   AND(1), OR(2), NOT(3), XOR(4)

   private BooleanOperators(int code) {
       this.code = code;
   }

   public int getCode() {
       return this.code;
   }
}

Then you can do ArithmeticOperators.ADD.getCode() , which will return the code associated with that enum. This method is safer because you can see the value being explicitly associated with the enum versus being implicitly associated based on their order of definition. So when you, or someone else adds a new enum, they are expected to associate a (hopefully unique) integer value with the new enum.

NOTE: The marker interface is not strictly necessary in this case; it just enforces the requirement that all enums that implement the interface should have the getCode() method. The following is just as valid:

public enum BooleanOperators {

   private int code;

   AND(1), OR(2), NOT(3), XOR(4)

   private BooleanOperators(int code) {
       this.code = code;
   }

   public int getCode() {
       return this.code;
   }
}

I assume this is what you want. If not, please let me know!

EDIT

Based on your comment, I would use a marker interface (let's call it Token ) that is applied to all your enums, and then use a map of type Map<String, Token> . You will initialize this map with your tokens and the corresponding enum. When your parser returns tokens, you can look up the enum using your map.

Use EnumSet to create subsets of your enum ; an example may be found here .

Good solution, but when you implement operators care about their priority, which also can be enum parameter. My approach was using separate group for each level of priority, and when i add them to the parser, i add them in order of priority.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM