ここに私の問題があります-私はArrayList.contains();
に相当する列挙型を探しています(存在する場合でも)。
コードの問題のサンプルを次に示します。
enum choices {a1, a2, b1, b2};
if(choices.???(a1)}{
//do this
}
ここで、ArrayList
のStrings
の方がこちらの方がよいルートであることに気付きましたが、他の場所のスイッチ/ケースを介して列挙型のコンテンツを実行する必要があります。したがって、私の問題。
このようなものが存在しないと仮定すると、どうすればそれを行うことができますか?
これはそれを行う必要があります:
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")
。
代わりにApache commons lang3 libを使用してください
EnumUtils.isValidEnum(MyEnum.class, myValue)
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
をクエリします。
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);
例えばこの:
enum MyData {
ONE,
TWO
}
@Test
public void test() {
if (!Enums.getIfPresent(MyData.class, "THREE").isPresent()) {
System.out.println("THREE is not here");
}
}
さらに良い:
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;
}
};
最初に列挙型をリストに変換してから、リストに含まれるメソッドを使用できます
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
}
これを使用できます
YourEnum {A1、A2、B1、B2}
boolean contains(String str){
return Sets.newHashSet(YourEnum.values()).contains(str);
}
ソリューションをより効率的にするために、@ wightwulf1944によって提案された更新が組み込まれています。
ここでいくつかのライブラリについて言及しましたが、私が実際に探していたライブラリが恋しいです:Spring!
ObjectUtils#containsConstant があります。これはデフォルトで大文字と小文字を区別しませんが、必要に応じて厳密にすることができます。次のように使用されます。
if(ObjectUtils.containsConstant(Choices.values(), "SOME_CHOISE", true)){
// do stuff
}
注:ここではオーバーロードメソッドを使用して、大文字と小文字を区別するチェックの使用方法を示しました。ブール値を省略して、大文字と小文字を区別しない動作にすることができます。
ただし、いくつかのようにMap実装を使用しないため、大きな列挙型には注意してください...
ボーナスとして、valueOfの大文字と小文字を区別しないバリアントも提供します。 ObjectUtils#caseInsensitiveValueOf
いくつかの仮定:
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);
}
}
あるとは思いませんが、次のようなことができます:
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のこのバージョンを参照してください。
これは私のために働く:
Arrays.asList(YourEnum.values()).toString().contains("valueToCheck");
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;
}
}
Apache Commonsを使用している場合(または使用したい場合)は、次の方法で確認できます。
ArrayUtils.contains(choices.values(), value)
この方法を使用して、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");
この検証用に次のクラスを作成しました
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);
}
グアバを使用すると、さらに簡単になります。
boolean isPartOfMyEnum(String myString){
return Lists.newArrayList(MyEnum.values().toString()).contains(myString);
}
Set.of(CustomType.values())
.contains(customTypevalue)
文字列で検索する場合は、valueOf("a1")
を使用できます
com.google.common.collect.Sets.newHashSet(MyEnum.values()).contains("myValue")
これは列挙型であり、これらは定数値であるため、switchステートメントの場合は次のようになります。
case: val1
case: val2
また、なぜ定数として宣言されているものを知る必要があるのですか?
これは、以前の方法のすべてのアプローチを組み合わせたものであり、同等のパフォーマンスが必要です。任意の列挙型に使用でき、@ 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));
}
}
}
値が存在するかどうかを確認するソリューションは、戻り値で列挙値を取得します:
protected TradeType getEnumType(String tradeType) {
if (tradeType != null) {
if (EnumUtils.isValidEnum(TradeType.class, tradeType)) {
return TradeType.valueOf(tradeType);
}
}
return null;
}