2

I need to use an Enum with a combobox (values shown below).

YES (shown as YES on UI, stored in DB as Y)
NO (shown as NO on UI, stored in DB as N)
DEFAULT (shown as "" on UI, stored in DB as null)

The Enum has methods to perform the following -

  1. toString() - to provide the custom String for UI. (showing the combo options)
  2. OptionToDB (static) - Convert a selected option to db value (on save / update)
  3. DBToOption (static)- Convert a DB value to selcted option (while loading the screen)

    static enum EnumOption{
        YES,NO,DEFAULT;
        ....
        public static EnumOption DBToOption(String val){
            if("Y".equals(val)){
                return YES;
            } else if("N".equals(val)){
                return NO;
            }else {
                return DEFAULT;
            }
        }
        ....
    }
    

It works pretty well, but the issue with above methods is that it uses if/else comparison to deduce which option / db value to be returned.

I thought of storing the dbValue as a field in enum but I was not able to reduce the if/else from DBToOption.

Can this if/else be avoided in any way using a better design??

Nrj
  • 6,723
  • 7
  • 46
  • 58
  • see also [this question](http://stackoverflow.com/questions/604424/java-convert-string-to-enum) and its second answer – arne.b Nov 26 '11 at 20:35

3 Answers3

4

If you store the dbValue as a field in the enum, you can remove the if/else and replace it with a for-loop, although I don't see anything wrong with those if/elses for this particular case:

static enum EnumOption {
  YES("Y"),
  NO("N"),
  DEFAULT("");

  private final String value;

  private EnumOption(String value) {
    this.value = value;
  }

  public static EnumOption DBToOption(String val) {
    for (EnumOption opt : EnumOption.values()) {
      if (opt.value.equals(val)) {
        return opt;
      }
    }
    return DEFAULT;
  }
}
João Silva
  • 89,303
  • 29
  • 152
  • 158
  • yeah I agree that its Ok to use if/else in this case, however it will be tedious when there are more options to handle. – Nrj Nov 27 '11 at 15:48
3
public enum EnumOption {

   YES("Y"), NO("N"), DEFAULT("");

   private final String value;

   private final static Map<String, EnumOption> options;

   static {
          options = new HashMap<String, EnumOption>();
          for (EnumOption opt : EnumOption.values()) {
                 options.put(opt.value, opt);
          }
   }

   private EnumOption(String value) {
          this.value = value;
   }

   public static EnumOption DBToOption(String val) {
          return options.get(val) != null ? options.get(val) : DEFAULT;
   }
}

And here is the test that proves it works.

public void testDBToOption() {      
    assertEquals(EnumOption.NO, EnumOption.DBToOption("N"));
    assertEquals(EnumOption.YES, EnumOption.DBToOption("Y"));
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption(""));
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption(null));
    assertEquals(EnumOption.DEFAULT, EnumOption.DBToOption("R"));
}
James DW
  • 1,815
  • 16
  • 21
  • thx this seems to do the trick ! I tried using the map myself however I was trying to set the map values from the constructor which was resulting in NPE. Thanks for showing this. – Nrj Nov 27 '11 at 15:31
0

So you want to get rid of the remaining if/else ...Are you doing Object Calisthenics?

You could do the following, if you do not have compatibility issues:

public enum EnumOption {

   Y("Y", "YES"), 
   N("N", "NO"), 
   D("D", "");

   private final String dbValue;
   private final String uiValue;

   private EnumOption(String dbValue, String uiValue) {
          this.dbValue = dbValue;
          this.uiValue = uiValue;
   }

   public String getDbValue() {
     return this.dbValue;
   }

   public String uiValue() {
      return this.uiValue;
   }

   public static EnumOption getFromDb(String dbValue) {
        return EnumOption.valueOf(dbValue);
   }
}

Since each enum value can only occur once, this has at least the same performance as all the other implementations.

For details about the automatically generated valueOf(String) method in enum types, and James DW's solution, you can read up in Josh Bloch's Effective Java Item 30 (Use enums instead of int constants), page 154.

DaveFar
  • 7,078
  • 4
  • 50
  • 90