3

私はJava列挙型を使用するのが初めてで、文字列リテラルを比較するIFロジックを列挙型に置き換える必要があることを読みました。以下のコードを列挙型に置き換える方法がよくわかりません。アイデアはありますか? applyEQ に渡される col 値に基づいて、その値に基づいて次のメソッド呼び出しを行う必要があります。col の可能な値を事前に知っているので、今のところ定数ファイルを使用しています。Enum を作成して、Interface of Constants ファイルに配置する必要がありますか?

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";
}
4

7 に答える 7

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;
}
于 2012-04-05T15:43:17.833 に答える
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()スローされる可能性があることに注意してください。IllegalArgumentExceptioncol.toUpperCase()

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);
    }
}
于 2012-04-05T15:47:59.020 に答える
2

Java Enum の優れた点は、タイプ セーフな列挙型パターンに対する言語レベルのサポートを提供することです。これは、メソッドを定義したり、メソッドをオーバーライドしたりできるためです。だからあなたはこれを行うことができます:

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);
}

-> switch ステートメントをポリモーフィズムに置き換えました!

于 2012-04-05T16:17:53.443 に答える
1

列挙型を作成するのが最善です。

    public Enum AvailableCols{
       COL_1,
       COL_2;
    }

プロシージャを次のように変換します

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

それでも文字列を保持したい場合は、次の投稿を見ることができます

于 2012-04-05T15:54:39.237 に答える
0

基本的に、列挙型を作成し、のタイプを変更して、またはの値を列挙型の値と比較するためにcol使用します。または、ステートメントを使用することもできますが、3つの定数だけでコードが読みやすくなるとは思えません。equals()==colswitch

例:

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: 
       ...

   }

}
于 2012-04-05T15:43:59.763 に答える
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;
    }      
}

そのようにデータを前処理すると、ロジックを理解しようとしているときに、列挙型の値にスイッチを使用できます。

于 2012-04-05T15:49:25.090 に答える
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);
}
于 2012-04-05T16:02:21.490 に答える