thatidiotguy
thatidiotguy

Reputation: 8991

Using integer values and String identifier in an Enum

So I currently have two enums:

public enum AuthorizationLevel 
    {   
        FULL,
        HALF,
        NONE;
    };


public enum DatabaseLoggingLevel
{
    HIGH,
    MED,
    LOW,
    AUTH_ONLY,
    NONE
}

I want to be able to associate integers with the values in the enums so that I can have code like so:

if(databaseLoggingLevel < ClassName.DatabaseLoggingLevel.HIGH) return;

This is just so that certain logging is disabled when the level is less than HIGH. I thought about making a helper function that returns an integer value associated with each enum value with a switch statement, but that seems hacky. Is there something I am missing?

Upvotes: 1

Views: 2339

Answers (6)

Arnaud Denoyelle
Arnaud Denoyelle

Reputation: 31225

Modify the constructor of your enum to add the Integer value.

public enum DatabaseLoggingLevel {
  HIGH(1),
  MED(2),
  LOW(3),
  AUTH_ONLY(4),
  NONE(5);

  private final Integer value;

  //For getByValue(). See Rohit's comment
  private static final DatabaseLoggingLevel[] VALUES = DatabaseLoggingLevel.values();

  private DatabaseLoggingLevel(Integer value) {
    this.value = value;
  }

  public Integer getValue() {
    return this.value;
  }

  //Bonus : getter by value:
  public static DatabaseLoggingLevel getByValue(Integer value) {
    for(DatabaseLoggingLevel e: VALUES) {
      if(e.getValue().equals(value)) {
        return e;
      }
    }
    return null;
  }
}

Upvotes: 3

Rohit Jain
Rohit Jain

Reputation: 213253

You can add an integer instance field to your enum, and add a parameterized constructor:

enum AuthorizationLevel {

    FULL(1), HALF(2), NONE(3);

    private final int level;

    private AuthorizationLevel(int level) {
        this.level = level;
    }

    public int getLevel() {
        return level;
    }
};

Note that there is an ordinal() method which will give you position of your enum constants, but you should avoid using it. Again, quoting Effective Java Item - 31 (Use instance fields instead of ordinal):

If the constants are reordered, the numberOfMusicians method will break. If you want to add a second enum constant associated with an int value that you’ve already used, you’re out of luck.

Also, you can’t add a constant for an int value without adding constants for all intervening int values. For example, suppose you want to add a constant representing a triple quartet, which consists of twelve musicians. There is no standard term for an ensemble consisting of eleven musicians, so you are forced to add a dummy constant for the unused int value (11). At best, this is ugly. If many int values are unused, it’s impractical.

Upvotes: 6

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

Rather than programming this in terms of "enums are numbers", program this in terms of "enums are smart". You can associate numbers with enums (after all, enums are instances of regular Java classes), but make that number private. Then you can add this method to the enum:

public boolean isAboveOrEqualTo(DatabaseLoggingLevel level) {
    ...
}

Then your conditional would look like this:

if (databaseLoggingLevel.isAboveOrEqualTo(ClassName.DatabaseLoggingLevel.HIGH)) {
    ...
}

Here is an explanation of how to associate numbers with enums: link.

Upvotes: 2

LiamRyan
LiamRyan

Reputation: 1898

While both of the answers given already will do what you want I would recommend looking at Log4J as an alternative to rolling your own logging levels

http://www.tutorialspoint.com/log4j/log4j_overview.htm

Upvotes: 0

mhenke
mhenke

Reputation: 246

Use the ordinal() method. It gives you the position of the Value in the enum.

Upvotes: 2

JNL
JNL

Reputation: 4703

public enum DatabaseLoggingLevel
{
    HIGH(1),
    MED(2),
    LOW(3),
    AUTH_ONLY(4),
    NONE(5)

    private int code;

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

    public int getCode() { return code; }

}

Upvotes: 2

Related Questions