Javaとは何ですか?:呼び出された演算子とは何ですか?


161

私は数年前からJavaを扱ってきましたが、最近までこの構造に出くわしていません。

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

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

  • 場合はisHeretrueで、getHereCount()呼ばれ、
  • isHere偽の場合はgetAwayCount()呼び出されます。

正しい?この構成は何と呼ばれますか?


2
この質問のC ++バージョンについては、stackoverflow.com / questions / 795286 / what-does-do- in - c も参照してください(実際、昨日尋ねました)。
マイケルマイヤーズ

2
C / C ++ / Javaの世界は、醜くて混乱し、ペストのように避けられると思う人と、C、C ++、またはJavaを本当に知っていると主張することができないと思う人の間ではかなり均等に分けられます。それを認識して、考えるのを止めずにそれを使用することはできません。
ポールトンブリン

3
最も明確で最も単純なケースを超えてそれを使用することは、Javaでは一般的に不適切なフォームと見なされます。あなたが自分でそれらをネストしているのを見つけたら、あなたは道を外れています。一方、高速で賢いコードが明快さより高く評価されるC文化では、それは許容できると見なされます。
Yishai

17
answer_to_question =(recognize_operator)?(social_acceptance):(condescending_finger_wag)
ダン

詳細については、このリソースを参照してください。
シバ

回答:


189

はい、それはの省略形です

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

これは条件演算子と呼ばれます。これ Java、C、C ++、およびおそらく他の多くの言語で唯一の3項(3引数)演算であるため多くの人は(誤って)3項演算子と呼びます。ただし、理論的に別の三項演算子が存在する可能性がありますが、条件演算子は 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 

下の方が何をしているのかよくわかりません。私はあなたとすべてを信じています。見た目はオリジナルと同じです。それは、値を返す場合と返さない場合がある別の関数を呼び出して、次のコードセットを実行できるようにするためですか?
ジョニー

8
doSomething()およびdoSomethingElse()はvoidメソッドであると想定しています。仕様の最後の部分で述べていることは、3項演算子値を返す必要があるため、どのオペランドもvoidメソッドにできないということです。
マイケルマイヤーズ

それはそれより少し多くを言います。voidメソッドCOULDが出現する場所では条件演算子は許可されていません。したがって、たとえば、次のステートメント:VALID:String x =(false)?"X": "Y"; 無効:(false)?"X": "Y";
kenj0418 2013年

4
オバマ氏を「大統領」と呼ぶのは(2016年に)誤りではないのと同様に、将来的に他の大統領が存在する可能性があるとしても、それを「三項演算子」と呼ぶことは誤りではありません。
Dawood ibnカリーム2016年

2
@DawoodibnKareem私はマイケルが意図的theにのイタリック体に含まれていると思いますthe ternary operator、そしてそれは彼が誤っていることを意味しているのではなく、間違っているという意味ですternary operator。マイケルが言うように三項演算子は、それが今度はマイケルが誤っていると言っている、と私は同意するだろう、それが何をしている、他の三項演算子はあり得ないと仮定して1を導くことができる唯一の人、である、ということを意味しますこと誤った仮定。
Ghotiとチップス2017

32

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

私はあくまでも責任者なので、演算子の名前が条件演算子または「条件演算子?:」であることを明確にしたいと思います。それはだ(それは3つのオペランドを持つことで)三項演算子と、現時点ではJavaで唯一の三項演算子であることを起こります。

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


3
この答えは技術的に正しいです。ただし、3項演算子は1つしかないため、3項演算子と呼ばれることがよくあります。この名前はオペレーターの完全な意味を伝えるものではありませんが、こだわった名前です。「三項演算子」という名前を言うと、プログラマはあなたが何を話しているのかを知っています。あなたが言及する仕様では、この演算子を「Ternary Conditional」と呼んでいます。 java.sun.com/docs/books/jls/third_edition/html/…–
ゲイリー

17
私は、定義された名前で何かを呼ぶ価値があると思います。特に、Javaが別の三項演算子を取得する場合でも、「条件演算子」という用語を使用する人々は、「三項演算子」と言うだけの人々とは異なり、正確で明確です。はい、「3項演算子」という語句が詰まっています-私の答えは、「オブジェクトが参照によって渡される」という主張を修正しようとするのと同じように、「解く」ための取り組みの一部です。
Jon Skeet、

1
3つの「条件演算子」について説明し、1つの「三項演算子」についてのみ説明しているOracleからのこのページに案内してもよいですか。どの演算子を使用するかを明確にしたい場合は、ほとんどの人が使用している名前を使用する方が良いでしょう。(はい、主催者が最後の皿を洗っているのと同じように、私はパーティーに来ていることを知っています)。
Dawood ibnカリーム2016年

@DavidWallace:「条件演算子?:」を使用する方が良い、IMO-編集してそれを明確にする。しかし、私は、その動作とは関係のない1つの側面(演算子の数)に焦点を当てるのではなく、実際の演算子名を使用するように人々を説得する価値があると思います。チュートリアル呼び出し仕様、より少ない正確であるために(それはまた珍しいことではありません&&条件付きと演算子を、および||条件付きまたはオペレータが、用途だけのための「条件演算子」?:
ジョンスキート

知りません。誰かが私に「条件付き演算子」と言ったら、私はそれらが何を意味するのかわかりません。私がどこから来たのか(あなたとは世界の反対側)、人々はこれをこれと呼ばないだけです。彼らが「三項演算子」または「フック演算子」と言ったら、私は理解します。人々の話し方を変えたいというあなたの野心に感心します。誰かがそれを行うことができれば、それはあなたです。しかし、私は多くの希望を差し控えたり、多くの要点を見たりしていません。
Dawood ibnカリーム

17

Sun Java仕様によれば、これは条件演算子と呼ばれています。セクション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番目の式の間に:が表示されます。

最初の式はブール型またはブール型でなければなりません。そうでないと、コンパイル時エラーが発生します。


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

手段 :

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

5

正確には正確ではありません:

  1. isHereがtrueの場合、getHereCount()の結果返されます
  2. その他、getAwayCount()の結果返されます。

その「返却」は非常に重要です。つまり、メソッド値を返す必要あり、その値どこかに割り当てる必要あります。

また、それはだ、正確ではない構文的に同等であれば、他のバージョンに。例えば:

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

if-elseを使用してコーディングすると、常にバイトコードが増えます。


私はjavacが同じバイトコードを生成する自由があると信じています。同等ではないあいまいなコーナーケースがあることは正しいですが。
トム・ホーティン-タックライン2009

はい、もちろん。私にとって、条件付き演算子の真のメリットは、私が与えた例です。代替案は次のいずれかです。文字列temp = str1; if(チェック)temp + = str2; それ以外の場合、temp + = str3; temp + = str4; 温度を返す; または、StringBuilder追加操作をハンドコーディングします。最初のものは深刻な効率の問題に苦しんでいますが、2番目のものは冗長すぎて、多くの利益なしに骨の折れる努力です。
RichN 2009

4

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

例えば:

public class Foo {
    final double    value;

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

その演算子がなければ、どのような名前でも、フィールドを非最終にするか、単に初期化するための関数を作成する必要があります。実際、それは正しくありません。少なくともJavaでは、if / elseを使用して初期化できます。しかし、私はこのクリーナーを見つけます。



3

この構造は、コンピュータサイエンスおよびプログラミング技術では3 項演算子と呼ばれます。
そしてウィキペディアは次の説明を提案しています:

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

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

次のリンクでは、次の説明が示されています。これを理解するのは静かです。

三項演算子は、3つの入力で動作するいくつかの操作です。これはif-elseステートメントのショートカットであり、条件演算子としても知られています。

Perl / PHPでは、次のように機能します。
boolean_condition ? true_value : false_value

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

これは、複雑すぎないいくつかの論理条件については読み取り可能かもしれません。そうでない場合は、条件付きロジックの意図された組み合わせでIf-Elseブロックを使用することをお勧めします

このTernary演算子を使用して、1つのコードステートメント行で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);
}

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


2

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


9
アリスインワンダーランドを引用すると、三項演算子と呼ばれますが、その名前は条件演算子です。
ポールトンブリン

ただし、その名前は疑問符のコロン演算子と呼ばれます。
マイケル・マイヤーズ

1
ネーミングネーミングサウンドは少しC ++風です。疑問符のコロン演算子?:(1つのトークン)はElvis演算子と呼ばれます。
トム・ホーティン-タックライン2009

2

その三項演算子(?:)

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.

1

条件演算子に似た新しい演算子の提案に興味があるかもしれません。nullセーフオペレーターは、次のようなコードを有効にします。

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

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

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

それはされていますさらなる検討のために選択 JDK 7の下の「プロジェクトコイン。」


そのオペレーターは、Project Coinでの私のお気に入りの1つではありません。限定された有用性、読むのは直感的ではなく、すべての外出のように醜いだけです。多分それは私に成長するでしょう。
マイケルマイヤーズ

実は私も大ファンではありません。それはNeal Gafterの提案であり、彼はあなたの平均的なJavaプログラマーとは非常に異なって物事を見る傾向があり、彼らはあなたの平均的な人間とは異なって物事を見る傾向がある。nullを少し手助けしたい唯一の場所は、foreachループ、反復可能オブジェクトがnullかどうかのテスト、および自動アンボックス化です。
エリクソン2009

IIRC <ニールはそれを提案しなかった。彼は提案を書く方法の簡単な例としてそれをちょうど使用しました。プロジェクトコインメーリングリストアーカイブの詳細。
トム・ホーティン-タックライン2009

私は提案のイントロを読んだだけで、あなたは正しいです。それはJodaのStephen Colebourneで、「Java 7はありません」の名声です。
エリクソン2009

1

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

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

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


0

これは条件演算子であり、ifステートメントを記述するための単なる簡潔な方法ではありません。

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


0

はい。それで合っています。?:通常、「3項演算子」と呼ばれ、単に「3項演算子」と呼ばれます。これは、標準のif / else条件付きの短縮形です。

三項条件演算子


0

私はたまたまこの演算子が好きですが、読者を考慮に入れるべきです。

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

まず、元のアスカーのケースがあります。彼はそれについて1時間投稿し、回答を読んだ。著者がすべてを書くのにどれくらい時間がかかりますか?:彼の人生の全過程を通してif / thenとして。確かに1時間ではありません。

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

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

私が長い間Rubyユーザーであった場合、おそらくこの行に問題はなかったでしょうが、Cから来た場合、行の最初に「callMethodWhatever」が表示されている場合、それが実行されることを期待しています。?:はそれほど不可解ではありませんが、それでも、読者を落とすほど十分に珍しいものです。

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

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


0

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

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

この条件式の結果は

boolean-expressionがtrueの場合はexpression1。

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

より大きな数の変数num1とnum2をmaxに割り当てたいとします。条件式max =(num1> num2)?num1:num2;

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.