web-dev-qa-db-ja.com

ifステートメントで複数の「または」条件をフォーマットする最良の方法(Java)

簡単な質問ですが、Googleはあまり役立っていません。

多くの条件を持つifステートメントがあります(10個または15個の定数をチェックして、それらのいずれかが存在するかどうかを確認する必要があります)。

次のようなものを書く代わりに:

if (x == 12 || x == 16 || x == 19 || ...)

のようにフォーマットする方法はありますか

if x is [12, 16, 19]?

これをコーディングする簡単な方法があるかどうか疑問に思うだけで、どんな助けも感謝します。

編集:答えは非常に役に立ちましたが、私は彼らの好奇心を満足させるためにそれをするつもりであるので、私は少数の人々により詳細を追加するように頼まれました。私は、30日しかない月(そのうち4日があると思う)で30日を超えないことを確認する必要がある日付検証クラスを作成し、次のようなことを確認するifステートメントを書いていました。

if (day > 30 && (month == 4 || month == 6 || month == 9 || month == 11))

そのようなことをコーディングするためのより速い方法があるかどうか疑問に思っていました-以下の答えの多くが助けになりました:)。

42
Anthony

私はこの種のパターンを頻繁に使用します。非常にコンパクトです。

_// Define a constant in your class. Use a HashSet for performance
private static final Set<Integer> values = new HashSet<Integer>(Arrays.asList(12, 16, 19));

// In your method:
if (values.contains(x)) {
    ...
}
_

ここでHashSetを使用して、良好なルックアップパフォーマンスを提供します-非常に大きなハッシュセットでも、contains()を非常に迅速に実行できます。

パフォーマンスが重要でない場合、その要点を1行にコーディングできます。

_if (Arrays.asList(12, 16, 19).contains(x))
_

しかし、実行するたびに新しいArrayListを作成することを知っています。

46
Bohemian

これに切り替えますか??

switch(x) {
    case 12:
    case 16:
    case 19: 
        //Do something
        break;
    default:
        //Do nothing or something else..
        break;
}
10
Gevorg

マップキーの存在を検索したり、マップキーがセットに含まれているかどうかを確認したりできます。

あなたが実際に何であるかに応じてdoing、しかし、あなたは問題を間違って解決しようとしている可能性があります:)

3
Dave Newton

ある種のコレクションを使用します-これにより、コードが読みやすくなり、すべての定数が非表示になります。簡単な方法はリストを使用することです:

// Declared with constants
private static List<Integer> myConstants = new ArrayList<Integer>(){{
    add(12);
    add(16);
    add(19);
}};

// Wherever you are checking for presence of the constant
if(myConstants.contains(x)){
    // ETC
}

ボヘミアンが指摘しているように、定数のリストは静的であるため、複数の場所からアクセスできます。

興味のある方のために、私の例のリストでは double brace initialization を使用しています。最近私はそれに出くわしたので、クイックでダーティなリストの初期化を書くのにうれしいことがわかりました。

3
filip-fku

可能性のセットが「コンパクト」(つまり、最大値-最小値が200未満)である場合、ルックアップテーブルを検討できます。これは、次のような構造がある場合に特に便利です。

if (x == 12 || x == 16 || x == 19 || ...)
else if (x==34 || x == 55 || ...)
else if (...)

実行するブランチを識別する値(上記の例では1、2、3)を使用して配列を設定すると、テストは次のようになります。

switch(dispatchTable[x])
{
    case 1:
        ...
        break;
    case 2:
        ...
        break;
    case 3:
        ...
        break;
}

これが適切かどうかは、問題のセマンティクスに依存します。

配列が適切でない場合は、Map<Integer,Integer>を使用できます。または、単一のステートメントのメンバーシップをテストするだけの場合は、Set<Integer>を使用できます。単純なifステートメントには大きな力がありますが、コンテキストがなければ、正しい方向に導くのは困難です。

3
Jim Garrison

いいえ、Javaではできません。ただし、次のようにメソッドを作成できます。

boolean isContains(int i, int ... numbers) {
    // code to check if i is one of the numbers
    for (int n : numbers) {
        if (i == n) return true;
    }
    return false;
}
3
fastcodejava

Java 8では、プリミティブストリームを使用できます。

if (IntStream.of(12, 16, 19).anyMatch(i -> i == x))

ただし、比較の数に応じて、わずかなオーバーヘッドが発生する場合があります(発生しない場合があります)。

2
assylias