今まで私は必要なすべての答えを見つけることができましたが、これは私を混乱させます。サンプルコードがあるとしましょう:
public class Animal {
private String species;
private boolean canHop;
private boolean canSwim;
public Animal(String speciesName, boolean hopper, boolean swimmer) {
species = speciesName;
canHop = hopper;
canSwim = swimmer;
}
public boolean canHop() { return canHop; }
public boolean canSwim() { return canSwim; }
public String toString() { return species; }
}
public interface CheckAnimal {
public boolean test(Animal a);
}
public class FindSameAnimals {
private static void print(Animal animal, CheckAnimal trait) {
if(trait.test(animal)){
System.out.println(animal);
}
public static void main(String[] args) {
print(new Animal("fish", false, true), a -> a.canHop());
}
}
OCA Study Guide(Exam 1Z0-808)bookは、これらの2行は同等であると述べています。
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
これは、舞台裏で、Javaがキーワードreturnをコードインに追加することを意味しますか?最初のケース?
答えがYESの場合、次のコードのコンパイル方法(他のすべてが適切な場所にあると想像してください):
static int counter = 0;
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> counter++));
executeおよびRunnableのrunのシグネチャが次のとおりであることがわかっている場合:
void execute(Runnable command)
void run()
答えがNOの場合、どのようにJava何かを返す必要があるのか、いつ返さないのかを知っていますか?
a -> a.canHop()
無視したい場合booleanメソッドの戻り値の型。
これは、舞台裏でJavaが最初のケースでコードにキーワードリターンを追加するということですか?
いいえ、コンパイラはバイトコードを生成します。同じバイトコードを生成する可能性がありますが、構文を変更せずに再度コンパイルします。
メソッドのブール戻り型を無視したかった。
考慮している機能インターフェイスに基づいて値を無視するオプションがあります。
_a -> a.canHop()
_
になり得る
_(Animal a) -> { return a.canHop(); }
_
または
_(Animal a) -> { a.canHop(); }
_
コンテキストに基づいていますが、可能であれば最初のものを優先します。
ExecutorService.submit(Callable<T>)
およびExecutorService.submit(Runnable)
を検討してください
_ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(() -> counter++); // has to be Runnable
es.submit(() -> counter++); // Callable<Integer> or Runnable?
_
戻り値の型を保存すると、_Callable<Integer>
_であることがわかります
_final Future<Integer> submit = es.submit(() -> counter++);
_
試してみてください、ここに長い例があります。
_static int counter = 0;
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
// execute only takes Runnable
es.execute(() -> counter++);
// force the lambda to be Runnable
final Future<?> submit = es.submit((Runnable) () -> counter++);
System.out.println(submit.get());
// returns a value so it's a Callable<Integer>
final Future<Integer> submit2 = es.submit(() -> counter++);
System.out.println(submit2.get());
// returns nothing so it must be Runnable
final Future<?> submit3 = es.submit(() -> System.out.println("counter: " + counter));
System.out.println(submit3.get());
es.shutdown();
}
_
プリント
_null
2
counter: 3
null
_
最初のsubmit
はRunnable
を取るため、Future.get()
はnull
を返します
2番目のsubmit
はデフォルトでCallable
であるため、Future.get()
は_2
_を返します。
3番目のsubmit
はvoid
戻り値にしかなれないため、Runnable
でなければならないので、Future.get()
はnull
を返します。
はい、単一のステートメントのみを指定する場合、その値はラムダから自動的に返されます。
次に、 Runnable
は関数型インターフェースであるため、ラムダとして定義できます。戻り値の型はvoid
であるため、ラムダ内の戻り値は無視されます。
return
ステートメントのスコープについて混乱しています。 return
ステートメント(コンパイラーによるバイトコードとして挿入されるか、プログラマーによるソースコードとして挿入される)は、ラムダを呼び出すメソッドからではなく、ラムダから返されます。
void foo() {
Supplier<String> s = () -> { return "bar" };
String s = s.get(); // s is assigned to "bar"
// Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method
System.out.println("This will print");
}