web-dev-qa-db-ja.com

Java:enumに特定の文字列が含まれているかどうかを確認しますか?

ここに私の問題があります-私はArrayList.contains();に相当する列挙型を探しています(存在する場合でも)。

コードの問題のサンプルを次に示します。

enum choices {a1, a2, b1, b2};

if(choices.???(a1)}{
//do this
} 

ここで、ArrayListStringsの方がこちらの方がよいルートであることに気付きましたが、他の場所のスイッチ/ケースを介して列挙型のコンテンツを実行する必要があります。したがって、私の問題。

このようなものが存在しないと仮定すると、どうすればそれを行うことができますか?

131
Jared

これはそれを行う必要があります:

public static boolean contains(String test) {

    for (Choice c : Choice.values()) {
        if (c.name().equals(test)) {
            return true;
        }
    }

    return false;
}

これにより、後で列挙値を追加することを心配する必要がなく、すべてチェックされます。

編集: 列挙が非常に大きい場合は、HashSetに値を固定できます。

public static HashSet<String> getEnums() {

  HashSet<String> values = new HashSet<String>();

  for (Choice c : Choice.values()) {
      values.add(c.name());
  }

  return values;
}

そうすれば、次のことができます:trueまたはfalseを返すvalues.contains("your string")

168
Richard H

代わりにApache commons lang3 libを使用してください

 EnumUtils.isValidEnum(MyEnum.class, myValue)
190
RaphC

Enum.valueOf()を使用できます

enum Choices{A1, A2, B1, B2};

public class MainClass {
  public static void main(String args[]) {
    Choices day;

    try {
       day = Choices.valueOf("A1");
       //yes
    } catch (IllegalArgumentException ex) {  
        //nope
  }
}

チェックが頻繁に失敗することが予想される場合は、他の例で示したように単純なループを使用することをお勧めします-列挙にmany値が含まれている場合、おそらく__aHashSetまたは文字列に変換された列挙値の類似物代わりにHashSetをクエリします。

44
nos

Java 1.8を使用している場合、Stream + Lambdaを選択してこれを実装できます。

public enum Period {
    DAILY, WEEKLY
};

//This is recommended
Arrays.stream(Period.values()).anyMatch((t) -> t.name().equals("DAILY1"));
//May throw Java.lang.IllegalArgumentException
Arrays.stream(Period.values()).anyMatch(Period.valueOf("DAILY")::equals);
26
Hao Ma

Guavas Enums はあなたの友達かもしれません

例えばこの:

enum MyData {
    ONE,
    TWO
}

@Test
public void test() {

    if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {
        System.out.println("THREE is not here");
    }
}
18
H6.

さらに良い:

enum choices {
   a1, a2, b1, b2;

  public static boolean contains(String s)
  {
      for(choices choice:values())
           if (choice.name().equals(s)) 
              return true;
      return false;
  } 

};
16

最初に列挙型をリストに変換してから、リストに含まれるメソッドを使用できます

enum Choices{A1, A2, B1, B2};

List choices = Arrays.asList(Choices.values());

//compare with enum value 
if(choices.contains(Choices.A1)){
   //do something
}

//compare with String value
if(choices.contains(Choices.valueOf("A1"))){
   //do something
}
9
Bikram

これを使用できます

YourEnum {A1、A2、B1、B2}

boolean contains(String str){ 
    return Sets.newHashSet(YourEnum.values()).contains(str);
}                                  

ソリューションをより効率的にするために、@ wightwulf1944によって提案された更新が組み込まれています。

7
greperror

ここでいくつかのライブラリについて言及しましたが、私が実際に探していたライブラリが恋しいです:Spring!

ObjectUtils#containsConstant があります。これはデフォルトで大文字と小文字を区別しませんが、必要に応じて厳密にすることができます。次のように使用されます。

if(ObjectUtils.containsConstant(Choices.values(), "SOME_CHOISE", true)){
// do stuff
}

注:ここではオーバーロードメソッドを使用して、大文字と小文字を区別するチェックの使用方法を示しました。ブール値を省略して、大文字と小文字を区別しない動作にすることができます。

ただし、いくつかのようにMap実装を使用しないため、大きな列挙型には注意してください...

ボーナスとして、valueOfの大文字と小文字を区別しないバリアントも提供します。 ObjectUtils#caseInsensitiveValueOf

7
Pim Hazebroek

いくつかの仮定:
1)例外的なフロー制御であるため、try/catchはありません
2)「含む」メソッドは、通常は数回実行されるため、高速でなければなりません。
3)スペースに制限はありません(通常のソリューションに共通)

import Java.util.HashSet;
import Java.util.Set;

enum Choices {
    a1, a2, b1, b2;

    private static Set<String> _values = new HashSet<>();

    // O(n) - runs once
    static{
        for (Choices choice : Choices.values()) {
            _values.add(choice.name());
        }
    }

    // O(1) - runs several times
    public static boolean contains(String value){
        return _values.contains(value);
    }
}
6
AndreyP

あるとは思いませんが、次のようなことができます:

enum choices {a1, a2, b1, b2};

public static boolean exists(choices choice) {
   for(choice aChoice : choices.values()) {
      if(aChoice == choice) {
         return true;
      }
   }
   return false;
}

編集:

Richardsが行うStringsを使用するように変換しない限り機能しないため、Richardのこのバージョンを参照してください。

3
jluzwick

これは私のために働く:

Arrays.asList(YourEnum.values()).toString().contains("valueToCheck");
2
EDiaz

Pabloの返信をvalueOf()と組み合わせてみませんか?

public enum Choices
{
    a1, a2, b1, b2;

    public static boolean contains(String s) {
        try {
            Choices.valueOf(s);
            return true;
        } catch (Exception e) {
            return false;
        }
}
2
Karthik. V

Apache Commonsを使用している場合(または使用したい場合)は、次の方法で確認できます。

ArrayUtils.contains(choices.values(), value)
2
deamon

この方法を使用して、Enumを確認できます。これをUtilsクラスに追加できます。

public static <T extends Enum<T>> boolean enumContains(Class<T> enumerator, String value)
{
    for (T c : enumerator.getEnumConstants()) {
        if (c.name().equals(value)) {
            return true;
        }
    }
    return false;
}

次のように使用します:

boolean isContained = Utils.enumContains(choices.class, "value");
1
Toni Almeida

この検証用に次のクラスを作成しました

public class EnumUtils {

    public static boolean isPresent(Enum enumArray[], String name) {
        for (Enum element: enumArray ) {
            if(element.toString().equals(name))
                return true;
        }
        return false;
    }

}

使用例:

public ArrivalEnum findArrivalEnum(String name) {

    if (!EnumUtils.isPresent(ArrivalEnum.values(), name))
        throw new EnumConstantNotPresentException(ArrivalEnum.class,"Arrival value must be 'FROM_AIRPORT' or 'TO_AIRPORT' ");

    return ArrivalEnum.valueOf(name);
}

Java 8以上を使用している場合、これを行うことができます。

boolean isPresent(String testString){
      return Stream.of(Choices.values()).map(Enum::name).collect(Collectors.toSet()).contains(testString);
}
0
Chirag C

グアバを使用すると、さらに簡単になります。

boolean isPartOfMyEnum(String myString){

return Lists.newArrayList(MyEnum.values().toString()).contains(myString);

}
0
chaiyachaiya
  Set.of(CustomType.values())
     .contains(customTypevalue) 
0

文字列で検索する場合は、valueOf("a1")を使用できます

0
Amir Afghani
com.google.common.collect.Sets.newHashSet(MyEnum.values()).contains("myValue")
0
cnmuc

これは列挙型であり、これらは定数値であるため、switchステートメントの場合は次のようになります。

case: val1
case: val2

また、なぜ定数として宣言されているものを知る必要があるのですか?

0
Woot4Moo

これは、以前の方法のすべてのアプローチを組み合わせたものであり、同等のパフォーマンスが必要です。任意の列挙型に使用でき、@ Richard Hの「編集」ソリューションをインライン化し、@ bestsssのような無効な値には例外を使用します。唯一のトレードオフは、クラスを指定する必要があることですが、これにより2行になります。

import Java.util.EnumSet;

public class HelloWorld {

static enum Choices {a1, a2, b1, b2}

public static <E extends Enum<E>> boolean contains(Class<E> _enumClass, String value) {
    try {
        return EnumSet.allOf(_enumClass).contains(Enum.valueOf(_enumClass, value));    
    } catch (Exception e) {
        return false; 
    }
}

public static void main(String[] args) {
    for (String value : new String[] {"a1", "a3", null}) {
        System.out.println(contains(Choices.class, value));
    }
}

}

0
user2910265

値が存在するかどうかを確認するソリューションは、戻り値で列挙値を取得します:

protected TradeType getEnumType(String tradeType) {
    if (tradeType != null) {
        if (EnumUtils.isValidEnum(TradeType.class, tradeType)) {
            return TradeType.valueOf(tradeType);
        }
    }
    return null;
}
0
Amar Magar