53

何も返さずに三項演算を行うことができるかどうか疑問に思っていました。

Java では不可能な場合、他の言語では可能ですか? 可能であれば、どの言語が適用されますか?

name.isChecked() ? name.setChecked(true):name.setChecked(false);
4

6 に答える 6

60

いいえ、できません。if-elseしかし、声明に対するこれのポイントは何ですか? あなたは本当に7人のキャラクターを救おうとしていますか?

if (name.isChecked()) {
    name.setChecked(true);
} else {
    name.setChecked(false);
}

または悪いスタイルを好む場合:

if (name.isChecked()) name.setChecked(true); else name.setChecked(false);

あなたができるという事実を気にしないでください(この場合):

name.setChecked(name.isChecked());

三項または「条件付き」演算子のポイントは、に条件を導入することです。言い換えれば、これは:

int max = a > b ? a : b;

これの省略形を意味します:

int max;
if ( a > b ) {
    max = a;
} else {
    max = b;
}

生成される値がない場合、条件演算子はショートカットではありません。

于 2012-02-26T05:42:11.980 に答える
15

何も返さずに三項演算を行うことができるかどうか疑問に思っていました。

いいえ、それはできません:

  1. 2 番目と 3 番目のオペランドは非 void 式である必要があります。つまり、何らかの実際の価値を生み出さなければなりません。

    「2 番目または 3 番目のオペランド式が void メソッドの呼び出しであることは、コンパイル時エラーです。」- JLS 15.25 .

  2. 三項式は式であり、ステートメントとして使用することはできません。

    「特定の種類の式は、セミコロンを続けてステートメントとして使用できます。」...そして三項式はそれらの種類の1つではありません - JLS 14.8

本当に三項式を使用したいが、式の値を使用したくない場合、最も簡単な方法は、値をダミー変数に割り当て、変数が使用されていないという警告を抑制する注釈を追加することです。

しかし、より良いアイデアは、平易なifステートメントを使用することです。

Java では不可能な場合、他の言語では可能ですか? 可能であれば、どの言語が適用されますか?

私は少し慣れていませんが、C、C++、および Perl では、値が使用されていない場所で任意の式を使用できると思います。

于 2012-02-26T06:12:07.333 に答える
7

場合によっては、メソッド引数に対して3項演算を使用して、要求を解決できます。

name.setChecked(name.isChecked() ? true : false);

ちなみに、あなたの問題に対する最善の解決策は

name.setChecked(name.isChecked());
于 2012-02-26T06:01:53.640 に答える
0

Javaでは、次のコードは使用できません。

(your-condition) ? (true-statements) : (false-statements)

サンプルの場合、次のsnipetコードをコンパイルすることはできません。

(1==1) ? System.out.println("") : System.out.println("");

次のコンパイルエラーが発生します。

The left-hand side of an assignment must be a variable
于 2012-02-26T05:48:46.027 に答える
0

何らかの値を返す必要がありますが、値を返さずに何らかのアクションを実行する void メソッドのように動作させたい場合は機能しません。

お役に立てれば...

于 2016-12-20T05:21:49.483 に答える
0

質問のユースケースは、次のステートメントと同等であるため、単なる例にすぎないと思います。

name.setChecked(name.isChecked());

...これも意味がありません。しかし、その意図は明確であり、関連するユースケースが実際に数多くあります。

唯一の実行可能な一般的な解決策は、次のようなヘルパー メソッドを追加することです。

static void ternaryVoid(boolean condition, Runnable ifTrue, Runnable ifFalse) {
    (condition ? ifTrue : ifFalse).run();
}

そしてそれを次のように使用します:

ternaryVoid(name.isChecked(), () -> name.setChecked(true), () -> name.setChecked(false));

しかし、それは三項演算子の優雅さを失い、コードの複数の部分で使用され、ナノ秒が問題にならない場合にのみ「努力」する価値があります。

しかし、if-else ステートメントに対するこれのポイントは何ですか? あなたは本当に7人のキャラクターを救おうとしていますか?

そのような声明が修辞的な質問の形で現れることに驚いています。はい、特に関数型プログラミングのコンテキストでは、4 行を節約してコードをよりエレガントにすることが重要です。

voidさらに、メソッドが complete を返すかどうかについては、少なくとも議論の余地がありVoidます。基本的に、完了したタスクの通知を返します。これが、論理的に、何かを返すか何も返さないかに関係なく、三項式が同等に意味をなす理由です。

condition ? doThis() : doThat();

以下は、毎秒数百万回の増分更新を処理する可能性があるクラスの実際の例です。

public class DataHandler {

    private final TreeMap<Integer, Long> tree = new TreeMap<>();

    public void onUpdate(int price, long amount) {
        if (amount == 0) {
            tree.remove(price);
        } else {
            tree.put(price, amount);
        }
    }
}

許可されている場合、onUpdate()メソッドは次のような素敵な三項式になります。

public void onUpdate(int price, long amount) {
    (amount == 0) ? tree.remove(price) : tree.put(price, amount); // compilation error
}

幸いなことに、このようないくつかのケースでは、両方のターゲット メソッドが値を返し、これらの値は同じ型ですLong。この場合です。これにより、メソッドが以前の atonUpdateを返すようにすることができます(これは便利です)。amountprice

public Long onUpdate(int price, long amount) {
    return (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}

... または、代わりに (たとえば、メソッドがインターフェースによって決定される場合)、ダミー変数を使用して、その無用の警告を抑制します。

public void onUpdate(int price, long amount) {
    @SuppressWarnings("unused")
    Long dummy = (amount == 0) ? tree.remove(price) : tree.put(price, amount);
}

それ以外の場合、これらのソリューションは適用できず、他の人が回答したように存在しません。たとえば、次のことを試すことができます。

Consumer<Void> dummy = (x) -> {};
dummy.accept(/*...*/);

しかし興味深いことに、2 行目は引数として何も指定せずにコンパイルします。

最善の一般的な解決策は、上記のヘルパー メソッドternaryVoid()です。

于 2020-07-28T20:42:30.347 に答える