18

Java 8ラムダの実装は変更される可能性があることを認識していますが、ラムダビルドb39では、ラムダ式が非void型を返す場合にのみ中括弧を省略できることがわかりました。たとえば、これは次のようにコンパイルされます。

public class Collections8 {
        public static void main(String[] args) {
                Iterable<String> names = Arrays.asList("Alice", "Bob", "Charlie");
                names.filter(e -> e.length() > 4).forEach(e -> { System.out.println(e); });
        }
}

しかし、次のように中括弧を削除します。

names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));

エラーが発生します

Collections8.java:6: error: method forEach in interface Iterable<T> cannot be applied to given types;
        names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));
                                         ^
  required: Block<? super String>
  found: lambda
  reason: incompatible return type void in lambda expression
  where T is a type-variable:
    T extends Object declared in interface Iterable

誰かがここで何が起こっているのか説明できますか?

4

4 に答える 4

23

ラムダ本体が単一の式またはvoidメソッドの呼び出しである場合は、中括弧を省略できます。すべての式は値に評価されるため、無効にすることはできません。

ラムダの本体がステートメントのブロックである場合(たとえば、一連の計算の後にreturnステートメントが続く場合)、またはラムダに値がなく(つまり、voidリターンタイプがある)、単一のvoidメソッド呼び出しではない場合は、ブロックを使用する必要がありますフォーム。ブラケットが必要です。

ブロックスタイルのラムダでは、値がreturnedの場合、可能なすべてのコードパスはreturn値またはthrowのいずれかである必要がありますThrowable

于 2012-06-21T20:10:44.397 に答える
11

これはまさに、EGが(ほとんど)構文について決定を下したということです。

いくつかの選択肢を検討した後、基本的にC#構文を採用することにしました。細かい点(たとえば、細い矢印と太い矢印、特殊なnilary形式など)についてはまだ検討する必要がありますが、メソッド参照構文についてはまだ決定されていません。

C#構文は次のとおりです。

lambda = ArgList Arrow Body
ArgList = Identifier
           | "(" Identifier [ "," Identifier ]* ")"
           | "(" Type Identifier [ "," Type Identifier ]* ")"
Body = Expression
           | "{" [ Statement ";" ]+ "}"

式は何かに評価されます。Javaでvoid式を使用することはできません。それは声明なので、あなたは{}それを回避する必要があります。

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html

于 2012-06-21T20:15:03.610 に答える
2

中括弧がない場合、ラムダは->演算子の後に1つの式を自動的に返します。
したがって、何も返さないラムダがある場合は、中括弧を使用する必要があります

于 2013-04-08T15:58:18.243 に答える
2

私はあなたのコードを試しましたが、最新のJREバージョンでは問題ないと思います。

以下は、私がOracleJavaのドキュメントから参照しているものです。

ラムダ式では、ステートメントを中括弧()で囲む必要があります{}。ただし、voidメソッドの呼び出しを中かっこで囲む必要はありません。
たとえば、有効なラムダ式は次のとおりです。

email -> System.out.println(email)

そして、ドキュメントは非常に明確に説明しています。これで問題が解決することを願っています。

参照:https ://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

于 2015-11-05T14:37:47.510 に答える