替换字符串文字If / elseIf阻止Enum

时间:2012-04-05 15:38:36

标签: java

我是使用Java Enums的新手,我读过更换IF逻辑,比较字符串文字应该用Enum替换。我不太明白如何用Enum替换我的下面的代码,任何想法?基于传递给applyEQ的col值,我需要对它的值进行下一个方法调用。我提前知道col的可能值,我现在正在使用常量文件。我应该创建一个枚举并将其放在我的常量接口文件中吗?

public class FilterHelper implements IFilterHelper {

   private final EQuery eQuery;

   public FilterHelper(EQuery query) {
      eQuery = query;
   }

    @Override
    public void applyEQ(String col, String val) throws Exception {
        int return = 0;
        if (col.equalsIgnoreCase(EConstants.NAME)) {
            ret = Sample.addName(eQuery, val);
        } else if (col.equalsIgnoreCase(EConstants.KEYWORDS)) {
            ret = Sample.addKey(eQuery, val);
        } else if (col.equalsIgnoreCase(EConstants.ROLE)) {
            ret = Sample.addRole(eQuery, val);
        }  

        if (return != 0) {
            throw new Exception("failed");
        }
    }
}

EConstants.java

public final class EConstants {    
    public static final String NAME = "cewName";
    public static final String KEYWORDS = "cewKeywords";
    public static final String ROLE = "cewRole";
}

7 个答案:

答案 0 :(得分:2)

您可以将您的EConstants重写为枚举:

public enum EConstants {
  NAME, KEYWORDS, ROLE
}

使用switch语句评估条件:

// col has type of EConstants
switch (col) {
  case NAME:
    // do something
    break;
  case KEYWORDS:
    // do something
    break;
  case ROLE:
    // do something
    break;
  default:
    // what to do otherwise
    break;
}

答案 1 :(得分:2)

首先创建一个enum

public enum EConstants {
    CEWNAME,
    CEWROLE,
    CEWKEYWORDS;
}

然后将col字符串转换为此enum并使用switch

public void applyEQ(String col, String val) throws Exception {
    int ret = 0;
    final EConstants constant = EConstants.valueOf(col.toUpperCase());
    switch(constant) {
        case CEWNAME:
            ret = Sample.addName(eQuery, val);
            break;
        case CEWROLE:
            ret = Sample.addRole(eQuery, val);
            break;
        case CEWKEYWORDS:
            ret = Sample.addKey(eQuery, val);
            break;
        default:
            throw new Exception("Unhandled enum constant: " + constant);
    }
}

请注意,如果EConstants.valueOf()与任何常量值都不匹配,IllegalArgumentException可能会抛出col.toUpperCase()

BTW我讨厌在多个地方初始化的局部变量(和break关键字),尝试提取方法:

final EConstants constant = EConstants.valueOf(col.toUpperCase());
final int ret = processSample(val, constant);

方法本身:

private int processSample(String val, EConstants constant) throws Exception {
    switch(constant) {
        case CEWNAME:
            return Sample.addName(eQuery, val);
        case CEWROLE:
            return Sample.addRole(eQuery, val);
        case CEWKEYWORDS:
            return Sample.addKey(eQuery, val);
        default:
            throw new Exception("Unhandled enum constant: " + constant);
    }
}

答案 2 :(得分:2)

Java Enums的优点在于它们为类型安全枚举模式提供语言级支持,因为它允许您定义方法甚至覆盖它们。所以你可以这样做:

public enum CewColumn {

NAME("cewName") {

    @Override
    public int add(EQuery eQuery, String val) {
        return Sample.addName(eQuery, val);
    }
}, 
KEYWORDS("cewKeywords") {

    @Override
    public int add(EQuery eQuery, String val) {
        return Sample.addKey(eQuery, val);
    }
}, 
ROLE("cewRole") {

    @Override
    public int add(EQuery eQuery, String val) {
        return Sample.addRole(eQuery, val);
    }
};

private final String colName;

private MyColumn(String colName) {
    this.colName = colName;
}

private static final Map<String, CewColumn> COLUMNS = new HashMap<>(values().length);
static{
    for (CewColumn cewColumn : values()){
        COLUMNS.put(cewColumn.colName, cewColumn);
    }
}

public abstract int add(EQuery eQuery, String val);

public static CewColumn getCewColumn(String colName){
    return COLUMNS.get(colName);
}
}

然后你可以像这样使用它:

CewColumn cewColumn = CewColumn.getCewColumn(colName);
if (cewColumn != null){
    int ret = cewColumn.add(eQuery, val);
}

- &GT;你用多态性替换了switch语句!

答案 3 :(得分:1)

最好创建一个枚举。

    public Enum AvailableCols{
       COL_1,
       COL_2;
    }

并将程序转换为

    public void applyEQ(AvailableCols col, String val) throws Exception { 
         switch(col){
             case COL1:
             ...

如果您仍希望保留字符串,则可以看到以下post

答案 4 :(得分:0)

基本上创建枚举并更改col的类型,并使用equals()==col的值与枚举值进行比较。或者你可以使用switch语句,但我怀疑这会使你的代码只有3个常量更具可读性。

示例:

enum EConstants {
   NAME,
   KEYWORDS,
   ROLE;
}

public void applyEQ(EConstants col, String val) throws Exception {
   if( col == EConstants.NAME ) {
    ...
   }
   ....
}

//or

public void applyEQ(EConstants col, String val) throws Exception {
   if( EConstants.NAME.equals(col) ) { //col might be null
    ...
   }
   ....
}

//or

public void applyEQ(EConstants col, String val) throws Exception {
   switch( col ) {
     case NAME: 
       ...
       break;
     case ROLE: 
       ...

   }

}

答案 5 :(得分:0)

http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

如果原始数据是字符串,则仍需要进行字符串比较以分配枚举。如果对结果数据进行大量比较,这可能会更快,但如果没有,则只会给代码增加复杂性。

您可以像集合一样迭代枚举的值,这在您需要添加常量时为您提供了优势。那还不错。

以下是如何操作:

public enum EConstants {
    NAME, KEYWORDS, ROLE
}
...
public EConstants setConstant(String from) {
    if (from.equalsIgnoreCase("cewName")) {
        return NAME;
    } else if (col.equalsIgnoreCase("cewKeywords")) {
        return KEYWORDS;
    } else if (col.equalsIgnoreCase("cewRole")) {
        return ROLE;
    }      
}

您以这种方式预处理数据,现在当您尝试找出逻辑时,可以使用枚举类型值的开关。

答案 6 :(得分:0)

这是给你的一招。否switch/case(只为EConstants提供更好的名称。)

public enum EConstants {
  NAME,
  KEYWORDS,
  ROLE;

  private interface Applier {
    void apply(EQuery query, String val);
  }

  public void apply(EQuery query, String val) {
    map.get(this).apply(query, val);
  }

  private static Map<EConstants, Applier> map = new HashMap<EConstants, EConstants.Applier>();
  static {
      map.put(NAME, new Applier() {

        @Override
        public void apply(EQuery query, String val) {
          Sample.addName(query, val);
        }

      });

      map.put(KEYWORDS, new Applier() {

        @Override
        public void apply(EQuery query, String val) {
          Sample.addKey(query, val);
        }

      });

      map.put(ROLE, new Applier() {

        @Override
        public void apply(EQuery query, String val) {
          Sample.addRole(query, val);
        }

      });
  }
}

现在你写一下:

@Override
public void applyEQ(EConstants econs, String val) {
    econs.apply(equery, val);
}