2016-04-26 12 views
3

Javaオプションの評価に問題がありました。次のテストを考えてみましょう:Javaオプションの評価側の効果

@Test 
public void test() { 
    System.out.println("GOT STRING: " + first().orElse(second())); 
} 

private Optional<String> first() { 
    System.out.println("Evaluating first"); 
    return Optional.of("STRING OPTIONAL"); 
} 

private String second() { 
    System.out.println("Evaluating second"); 
    return "SECOND STRING"; 
} 

私の期待は、first()が空ではないことを返します。オプションで、その2番目は評価されません。しかし、実際に出力されている:

テストでorElseで使用される機能を試す
Evaluating first 
Evaluating second 
GOT STRING: STRING OPTIONAL 

@Test 
public void test2() { 
    System.out.println("GOT STRING: " + (first() != null ? "FIRST IS NOT NULL" : second())); 
} 

出力:

Evaluating first 
GOT STRING: FIRST IS NOT NULL 

なぜ評価され2番目のオプションはありますか?これは悪いようですか?

+0

を期待するorElseGetを使用することができ、サプライヤーを提供したり、熱心に実行を避けるために必要がある場合。おそらく 'orElseGet(...)'が必要になるでしょう。あなたのコード内の任意のラムダ式を持っていないとき – khelwood

+0

はなぜあなたの質問には、「ラムダ」でタグ付けされましたか? –

+0

は常にグーグルは、ラムダを与えるのでとorElseGetは、主に、ラムダ構築物で使用されています。 –

答えて

4

なぜ2番目のオプションが評価されますか?

orElse()に引数として値を提供するために、second()メソッドを呼び出すためです。引数の値は無視されます(すでに値が設定されているため)。ただし、引数を指定する必要はありません。

基本的には、このコード:

first().orElse(second()) 

は同等です:ここでは、オプションの固有

Optional<String> tmp1 = first(); 
Optional<String> tmp2 = second(); 
Optional<String> result = tmp1.orElse(tmp2); 

あります何も - それは、常にどのように引数の評価Javaで作品です。これはライブラリ構築物(orElse)とのいずれかのみ二または第三のオペランドを評価する条件演算子言語構築物(?:)との間に大きな違いはありませんが、決して両方のことを

注意。

アルトゥールが述べたように、あなたはsecond()への呼び出しを延期したい場合、あなたはorElseGetを使用する必要がある、あなたが渡す引数がfirstが1つを持っていない場合に使用する値ではありませんが、電話がかかって作りますの値を取得してください。

+0

この言語構​​造を使用するorElseの実装を見てきました。だから、私はこれと同じように動作しなければならない。しかしあなたの説明はここに適合します。これは私にとってはまだ簡単なエラーの原因と思われ、文書化されるべきです。あなたは評価が正しいですが。私はちょうどその機能を使用して忘れてちょっと。 –

9

関数自体への参照を渡すのではなく、値としてsecond()の値を渡すので、評価されます。次のいずれかを実行する必要があります。

System.out.println("GOT STRING: " + first().orElseGet(() ->second())); 
System.out.println("GOT STRING: " + first().orElseGet(this::second)); 

評価が本当に必要になるまで延期するには

2

メソッドorElsesecond()呼び出しがパラメータとして渡され、パラメータがJavaで賢く評価されるためです。

は、あなたはあなたが `orElse(...)を呼び出した場合は、`、引数は間違いなく評価されますSupplier

optional.orElseGet(()->second())) 
関連する問題