Diana Amza
Diana Amza

Reputation: 303

Working with <key, value> enums in a clean way

I'm looking for ways to implement and access my enum and I'm not very happy with how nice the code looks. It seems like a patched way. So here is what I'm trying to do:

Consider this simple enum as an example of what I'm trying to do:

public enum MyEnum {

  FIRST(0L), SECOND(1L), THIRD(2L);
  private Long number;

  private MyEnum(Long number){
    this.number= id;
  }

  public static boolean isFirst(MyEnum type) {
    return type == FIRST;
  }

  public static boolean isSecond(MyEnum type) {
    return type == SECOND;
  }

  public static boolean isThird(MyEnum type) {
    return type == THIRD;
  }

  public Long getId() {
    return number;
  }

}

Later on, I have some objects that I set as Long.valueOf(1L), and compare them with this enum using

Long.valueOf(1L).equals(instanceOfMyEnum.getId())

I really hate having those hardcoded constants all over my code so I was wondering if it's a bad practice to use something like this instead:

eMyEnum.FIRST.getId().equals(instanceOfMyEnum.getId())

or

someLongThatIPassAsParameter = eMyEnum.FIRST.getId(); 

These are just some simple examples but basically it's the same problem repeated over and over. What do you think?

Upvotes: 1

Views: 454

Answers (4)

Daniel Conde Garcia
Daniel Conde Garcia

Reputation: 295

Im not sure if I understood your question correctly, but what about using switch for the checks this for the checks?

 public enum MyEnum {

              FIRST(0L), SECOND(1L), THIRD(2L);
              private Long number;

              private static Map<Long, MyEnum> byIds = new HashMap<Long, PlaceServiceV2.MyEnum>();
              static{
                  for(MyEnum myEnum :MyEnum.values()){
                      byIds.put(myEnum.number, myEnum);
                  }

              }

              private MyEnum(Long number){
                this.number = number;   
              }

              public static MyEnum getById(Long id) {
                return byIds.get(id);
              }

              public Long getId() {
                return number;
         }
        }

public void test(){
    switch (MyEnum.getById(1L)) {
    case FIRST:

        break;
    case SECOND:

        break;

    default:
        break;
    }
}

Upvotes: 2

Kamil Mikolajczyk
Kamil Mikolajczyk

Reputation: 911

Apparently although you created an enum, your are still using these Long values everywhere, so maybe you can just use something like:

public class TypeOfSomething {
    public static final long FIRST = 1l;
    public static final long ANALOG = 2l;
    public static final long USB = 3l;
}

and then use them like:

someLongThatIPassAsParameter = TypeOfSomething.ANALOG; 

enum way is also fine, but I use it in case where it is more comfortable to use enum values in parameters, and value within enum is just additional information (e.g. messages.properties keys for internationalisation)

Upvotes: 0

Bal&#225;zs &#201;des
Bal&#225;zs &#201;des

Reputation: 13807

If you have a lots of enum values, i would do something like this (No need to modify the code if you add new ones):

public enum MyEnum {
    FIRST(0L), SECOND(1L), THIRD(2L);

    private Long number;

    /**
     * Lookup map, to provide a quick way to access your enums by id
     */
    private static final Map<Long, MyEnum> LOOKUP = new HashMap<Long, MyEnum>();

    /**
     * Static initializer, which loads your enums values runtime, and maps them
     * to their 'number' member.
     */
    static {
        MyEnum[] enums = MyEnum.class.getEnumConstants();
        for(MyEnum en : enums){
            LOOKUP.put(en.number, en);
        }
    }

    private MyEnum(final Long number) {
        this.number = number;
    }

    /**
     * Gets the enum value associated with the parameter, id.
     * @param id The id, that identifies your enum value
     * @return The enum value, or null, if not found.
     */
    public static MyEnum getById(final Long id){
        return LOOKUP.get(id);
    }
}

Upvotes: 3

mikea
mikea

Reputation: 6667

Why not implement a fromLong method in the enum

public static MyEnum fromLong(long l) {
    switch (l) {
    {
      case 0: return FIRST;
      case 1: return SECOND;
      case 2: return THIRD;
    }
    throw new IllegalArgumentException();
}

and then convert longs to the enum and compare enums. So you would have:

MyEnum.fromLong(longValue) == MyEnum.FIRST

Upvotes: 1

Related Questions