コードはコンパイルしないでください。なぜ型推論はJavaのlambdaとメソッド参照で同じように動作しないのですか?
public class MyClass {
...........
private void setEndDateOfValidStatusToCurrentTime(List<LifecycleStatus> oldStatuses, Date currentTime)
{
oldStatuses.stream()
.filter(oldStatus -> isValidNow(oldStatus, currentTime))
.findFirst().ifPresent(oldStatus -> oldStatus.setValidToDate(currentTime));
}
private boolean isValidNow(LifecycleStatus lifecycleStatus, Date currentTime)
{
Date start = lifecycleStatus.getValidFromDate();
Date end = lifecycleStatus.getValidToDate();
Date startTime = Optional.ofNullable(start).orElse(new Date(0L)); // BEGINNING OF TIME
Date endTime = Optional.ofNullable(end).orElse(new Date(Long.MAX_VALUE)); // END OF TIME
return startTime.before(currentTime) && endTime.after(currentTime);
}
}
理由: Iフィルタ方法は、それを必要とするので述語インタフェースを標的化するためにラムダにisValidNow()を使用しています。しかし、isValidNow()は2引数のメソッドであり、Predicateのtest()は1つの引数しか必要としません!
私はJavaコンパイラが型推論の力を持っていることを知っています。このような能力を持つスマートコンパイラは、isValidNow()を内部的に分解し、2番目の引数(currentTime)を安全に置き、最初の引数(oldStatus)だけを使ってPredicateでtest()を満たす実装を作り出すことを決定します。 。
代わりにメソッド参照を使用しようとすると、型推論が機能しないのはなぜですか?私は
filter(this::isValidNow)
で
filter(oldStatus -> isValidNow(oldStatus, currentTime))
を交換する場合興味深いことに、私はこれらのコンパイラエラーを参照してください。
- The method filter(Predicate<? super LifecycleStatus>) in the type Stream<LifecycleStatus> is not applicable for the arguments
(this::isValidNow)
- MyClass does not define isValidNow(LifecycleStatus) that is applicable here
ラムダ式の右辺にある1つの引数の述語法テスト(T t)に従うために、私が望むだけ多くの引数を持つメソッドを使うことができますか?サイドには1つしかありませんか? – softwarelover
@softwarelover - lambdaは(この場合)1つの引数と式の間のマッピングです。その式はあなたが望むものであれば何でもかまいません(型が正しいことを前提とします)。 –
oldStatusが引数として渡されるPredicate実装の等価コードを参照してください。 currentTimeはどうですか? test()メソッドはisValidNow()を呼び出しますが、test()はcurrentTimeをどのように知っていますか?私はcurrentTimeの宣言を見ません。どうか明らかにしてください。 – softwarelover