14

2つの異なる列挙型があり、特定の文字列が列挙型コレクションの一部であるかどうかを出力できるようにしたいです。これは私のコードです:

public class Check {
    public enum Filter{SIZE, DATE, NAME};
    public enum Action{COPY, DELETE, REMOVE};

    public boolean isInEnum(String value, Enum e){
        // check if string value is a part of a given enum
        return false;
    }

    public void main(){
        String filter = "SIZE";
        String action = "DELETE";
                // check the strings
        isInEnum(filter, Filter);
        isInEnum(action, Action);
    }
}

eclipseは、最後の2行で「フィルターを変数に解決できない」と述べていますが、それを除けば、関数「isInEnum」のEnumパラメーターが間違っているようです。

ここで何かが非常に間違っています誰かが助けることができますか?

4

6 に答える 6

21

最も簡単な(そして通常最も効率的な)方法は次のとおりです。

public <E extends Enum<E>> boolean isInEnum(String value, Class<E> enumClass) {
  for (E e : enumClass.getEnumConstants()) {
    if(e.name().equals(value)) { return true; }
  }
  return false;
}

次に、を呼び出しますisInEnum(filter, Filter.class)

于 2012-04-17T21:31:34.787 に答える
11

Apache commons lang3ライブラリを使用してもかまわない場合は、次のコードを使用できます。

EnumUtils.isValidEnum(Filter.class, filter)

ドキュメントによると:

このメソッドは、無効な列挙型名に対して例外をスローしないという点でEnum.valueOf(java.lang.Class、java.lang.String)とは異なります。

于 2016-03-09T08:03:31.493 に答える
6

これは、LouisWassermanの回答のJava8/streamsバージョンです。(このメソッドを直接Enumクラスに配置し、パラメーターの1つを削除することもできます)

public boolean isInEnum(String value, Class<E> enumClass) {
    return Arrays.stream(enumClass.getEnumConstants()).anyMatch(e -> e.name().equals(value));
  }
于 2015-11-10T19:20:26.877 に答える
3

サイモンタワーの答えに直接コメントするのに十分なポイントはありませんが、列挙型クラス自体に直接入る、彼が言及した2番目の方法のメソッドは次のとおりです。

 public static boolean isInEnum(String value) {
     return Arrays.stream(EnumClassNameGoesHere.values()).anyMatch(e -> e.name().equals(value));
}
于 2015-11-17T23:09:33.397 に答える
0

検証を行うためにループを使用することは避けてください。

を使用することをお勧めしvalueOfます。このメソッドは列挙型に組み込まれており、コンパイル時の最適化を検討することができます。

これは、ルックアップを最適化するために静的を実装するのと似てMap<String,EnumType>います。これは、他の考慮事項です。

欠点は、列挙型以外の値をキャッチするには、例外処理メカニズムを使用する必要があることです。

public enum DataType {
  //...
  static public boolean has(String value) {
    if (value== null) return false;
    try { 
        // In this implementation - I want to ignore the case
        // if you want otherwise ... remove .toUpperCase()
        return valueOf(value.toUpperCase()); 
    } catch (IllegalArgumentException x) { 
        // the uggly part ...
        return false;
    }
  }
}

また、上記のタイプの実装では、呼び出し時にコードがはるかにきれいに見えることにも注意してください。メインは次のようになります。

public void main(){
    String filter = "SIZE";
    String action = "DELETE";

    // ...

    if (Filter.has(filter) && Action.has(action)) {
      // Appropriate action
    }
}

次に、他の言及されたオプションは静的マップを使用することです。このようなアプローチを使用して、他のプロパティに基づいてあらゆる種類のインデックスをキャッシュすることもできます。以下の例では、各列挙値にエイリアス名のリストを含めることができます。この場合のルックアップインデックスは、大文字にすることにより、大文字と小文字を区別しません。

public enum Command {
  DELETE("del","rm","remove"),
  COPY("cp"),
  DIR("ls");

  private static final Map<String,Command> ALIAS_MAP = new HashMap<String,Command>();
  static {
    for (Command type:Command.values()) {
      ALIAS_MAP.put(type.getKey().toUpper(),type);
      for (String alias:type.aliases) ALIAS_MAP.put(alias.toUpper(),type);
    }
  }

  static public boolean has(String value) {
    return ALIAS_MAP.containsKey(value.toUpper());
  }

  static public Command fromString(String value) {
    if (value == null) throw new NullPointerException("alias null");
    Command command = ALIAS_MAP.get(value);
    if (command == null) throw new IllegalArgumentException("Not an alias: "+value);
    return command;
  }

  private List<String> aliases;
  private Command(String... aliases) {
    this.aliases = Arrays.asList(aliases);
  }
}
于 2012-09-28T18:52:07.060 に答える
0

これは、次のように実行することもできます。

public boolean isInEnum(String value, Enum e){
    return Enums.getIfPresent(e.class, value).isPresent();
}

詳細については、こちらをご覧ください

于 2021-05-04T14:47:44.537 に答える