web-dev-qa-db-ja.com

Java?:演算子とは何ですか?演算子は何をしますか?

私は数年Javaを扱ってきましたが、最近までこのコンストラクトに出くわしていませんでした。

int count = isHere ? getHereCount(index) : getAwayCount(index);

これはおそらく非常に単純な質問ですが、誰かがそれを説明できますか?どうやって読むの?私はそれがどのように機能するかを知っていると確信しています。

  • isHereがtrueの場合、getHereCount()が呼び出され、
  • isHereがfalseの場合、getAwayCount()が呼び出されます。

正しい?このコンストラクトは何と呼ばれていますか?

142
mainstringargs

はい、それはの短縮形です

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

条件演算子と呼ばれます。多くの人が(間違って)三項演算子と呼びます。これは、Java、C、C++、およびおそらく他の多くの言語で唯一の三項(3つの引数)演算子だからです。しかし、理論的にはcouldがもう1つの三項演算子であるのに対して、conditional operatorは1つしかありません。

正式名は Java言語仕様 で指定されています:

§15.25条件演算子? :

条件演算子? :は、1つの式のブール値を使用して、他の2つの式のどちらを評価するかを決定します。

両方のブランチが戻り値を持つメソッドにつながる必要があることに注意してください。

2番目または3番目のオペランド式のいずれかがvoidメソッドの呼び出しである場合、コンパイル時エラーです。

実際、式ステートメントの文法により( §14.8 )、voidメソッドの呼び出しが現れる可能性のあるコンテキストで条件式を表すことは許可されていません。 =

したがって、doSomething()doSomethingElse()がvoidメソッドの場合、これを圧縮することはできません。

if (someBool)
    doSomething();
else
    doSomethingElse();

これに:

someBool ? doSomething() : doSomethingElse();

簡単な言葉:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 
178
Michael Myers

他の人はこれに合理的な範囲で答えましたが、多くの場合、「三項演算子」という名前が付いています。

私は人間であるため、演算子の名前が条件演算子または「条件演算子?:」であることを明確にしたいと思います。それはa三項演算子(3つのオペランドがあるという点)であり、たまたまJavaの唯一の三項演算子です。

ただし、 仕様はかなり明確です その名前が条件演算子または「条件演算子?:」であることは、完全に明確です。演算子の数だけでなく、演算子の動作をある程度示す(条件の評価)ので、その名前で呼び出す方が明確だと思います。

30
Jon Skeet

Sun Java Specification によれば、これは条件演算子と呼ばれています。セクション15.25を参照してください。あなたはそれが何をするかについて正しいです。

条件演算子? :1つの式のブール値を使用して、他の2つの式のどちらを評価するかを決定します。

条件演算子は構文的に右結合(右から左にグループ化)されるため、a?b:c?d:e?f:gはa?b:(c?d:(e?f :g))。

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

条件演算子には3つのオペランド式があります。 ?最初の式と2番目の式の間に表示され、2番目と3番目の式の間に:が表示されます。

最初の式はブール型またはブール型である必要があります。そうでない場合、コンパイル時エラーが発生します。

17
JRL

正確に言えば、正確ではありません:

  1. isHereがtrueの場合、getHereCount()のresultreturned
  2. その他-結果 getAwayCount()の返される

「返される」ことは非常に重要です。これは、メソッドmustが値を返し、その値mustがどこかに割り当てられることを意味します。

また、正確ではない if-elseバージョンと構文的に同等です。例えば:

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

If-elseでコーディングすると、常により多くのバイトコードが生成されます。

5
RichN
int count = isHere ? getHereCount(index) : getAwayCount(index);

手段 :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}
4
Romain Linsolas

三項、条件付き。トマト、トマト。本当に価値があるのは変数の初期化です。 (私のように)変数が定義されている場合に変数を初期化するのが好きな場合、条件付き三項演算子(両方の場合)により、値に条件がある場合にそれを行うことができます。最終フィールドでは特に注目に値しますが、他の場所でも役立ちます。

例えば。:

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

その演算子なしで-名前を問わず-フィールドを非ファイナルにするか、単にフィールドを初期化するために関数を記述する必要があります。実際、そうではありません-if/elseを使用して初期化できます。少なくともJavaでは。しかし、私はこのクリーナーを見つけます。

3
Carl Manaster

このコンストラクトは、コンピューターサイエンスとプログラミング技術ではTernary Operatorと呼ばれます。
そして Wikipedia は以下の説明を提案します:

コンピューターサイエンスでは、三項演算子(三次演算子と呼ばれることもあります)は、3つの引数を取る演算子です。引数と結果はさまざまなタイプにすることができます。 Cのような構文を使用する多くのプログラミング言語は、条件式を定義する三項演算子?:を備えています。

Javaだけでなく、この構文はPHP、Objective-Cでも使用できます。

次の link では、次の説明がありますが、理解するのに適しています。

三項演算子は、3つの入力を操作する操作です。 if-elseステートメントのショートカットであり、条件演算子とも呼ばれます。

Perl/PHPでは次のように動作します:
boolean_condition ? true_value : false_value

C/C++では、次のように機能します:
logical expression ? action for true : action for false

これは、複雑すぎない一部の論理条件では読み取り可能です。そうでない場合は、条件ロジックの意図した組み合わせでIf-Else blockを使用することをお勧めします。

1つのコードステートメント行に対して、この3項演算子を使用してIf-Elseブロックを簡略化できます。
例:

if ( car.isStarted() ) {
     car.goForward();
} else {
     car.startTheEngine();
}

以下と等しい場合があります。

( car.isStarted() ) ? car.goForward() : car.startTheEngine();

したがって、あなたの声明を参照すると:

int count = isHere ? getHereCount(index) : getAwayCount(index);

実際には、次のIf-Elseブロックと100%同等です:

int count;
if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

それでおしまい!
これが誰かに役立つことを願っています!
乾杯!

3
Randika Vishman
condition ? truth : false;

条件がtrueの場合、最初のパラメーターを返します。条件がfalseの場合、2番目のパラメーターを返します。

これは 条件演算子 と呼ばれ、 三項演算 のタイプです。

3
Joe Phillips

正しい。それはcalled三項演算子 です。 条件演算子 と呼ばれることもあります。

2
cletus

その三項演算子(?:)

The ternary operator is an operator that takes three arguments. The first 
argument is a comparison argument, the second is the result upon a true 
comparison, and the third is the result upon a false comparison.
2
Darsy

実際には、3つ以上の引数を取ることができます。たとえば、数値が正、負、またはゼロであるかどうかを確認する場合は、次のようにします。

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

if、else if、elseを使用するよりも優れています。

1
Praised

条件演算子に似ているいくつかの新しい演算子の 提案 に興味があるかもしれません。ヌルセーフ演算子は、次のようなコードを有効にします。

String s = mayBeNull?.toString() ?: "null";

自動ボックス化解除が行われる場合、特に便利です。

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

さらに検討するために選択 JDK 7の「プロジェクトコイン」の下。

1
erickson

私はたまたまこの演算子が好きですが、読者を考慮する必要があります。

あなたは常にコードのコンパクトさとそれを読むのに費やした時間のバランスをとる必要があり、それはいくつかのかなり深刻な欠陥を持っています。

まず、オリジナルのアスカーのケースがあります。彼はそれについて1時間投稿し、回答を読んだだけです。著者がすべてを書くのにどれくらいの時間がかかったでしょうか?:生涯を通じてif/thenとして。確かに1時間ではありません。

第二に、Cライクな言語では、条件文が最初の行であることを単純に知る習慣がつきます。 Rubyを使用していたときにこれに気付き、次のような行に遭遇しました。

callMethodWhatever(Long + Expression + with + syntax) if conditional

私が長い間Rubyユーザーだったなら、おそらくこの行で問題はなかっただろうが、Cから来て、行の最初のものとして「callMethodWhatever」を見るとき、あなたはそれを期待する実行されます。 ?:はわかりにくいですが、読者を惑わすほど珍しいです。

ただし、1行のスペースに3行のifステートメントを記述できると、おなかがすっきりするという利点があります。それを否定することはできません:)しかし、正直なところ、90%の人々が必ずしもその希少性のために、必ずしもより読みやすいとは限りません。

ブール値と値に基づく割り当てである場合、問題はありませんが、簡単に悪用される可能性があります。

0
Bill K

条件式は完全に異なるスタイルであり、ステートメントに明示的なifはありません。

構文は次のとおりです。boolean-expression? expression1:expression2;

この条件式の結果は

boolean-expressionがtrueの場合はexpression1。

それ以外の場合、結果はexpression2です。

より多くの変数num1およびnum2をmaxに割り当てたいとします。条件式を使用してステートメントを簡単に書くことができます:max =(num1> num2)? num1:num2;

注:記号? and:条件式に一緒に現れます。これらは条件演算子を形成し、3つのオペランドを使用するため、三項演算子とも呼ばれます。 Javaで唯一の三項演算子です。

引用元:Javaの紹介Y. Daniel Liangによるプログラミング第10版126〜127ページ

0
Ged

はい。それで合っています。 ?:通常、「三項条件演算子」と呼ばれ、しばしば「三項演算子」と呼ばれます。これは、標準のif/else条件の簡略版です。

三項条件演算子

0
Gary

これは条件演算子であり、ifステートメントを記述する簡潔な方法以上のものです。

値を返す式なので、他の式の一部として使用できます。

0
justinhj