私はラムダ式がどのように機能するかを知っており、それがフィルタリングする基準を確立するのが.filter()
の引数であることを知っています。しかし、.filter()
が引数を使用する方法(この場合はラムダ式)がわかりません。filter()には実装がないか、少なくともコンパイル時に実装が必要なためです。私はOracleのサイトでこの未知の実装を検索しましたが、それがどのように機能するかを説明する数語しかなく、コードはまったくありません。
その実装は非表示ですか、Javaコンパイラによって自動的に作成されますか?
集約操作には1つ必要ですか?
double average = roster
.stream()
.filter(p -> p.getGender() == Person.Sex.MALE)
.mapToInt(Person::getAge)
.average()
.getAsDouble();
roster
はList<Person>
のArrayList<Person>
インスタンスです
Person
は人を表す単純なクラスです
ラムダオブジェクトは、コンパイラによって自動的に作成されます。
「機能的な」インターフェース(つまり、機能が1つだけのインターフェース)を1つのターゲットにすることができます。同等の非ラムダコードは次のようになります。
double average = roster
.stream()
.filter(new Predicate<Person>(){
public boolean test(Person p){
return p.getGender() == Person.Sex.MALE;
}
})
.mapToInt(Person::getAge)
.average()
.getAsDouble();
コンパイラーによってこの方法で実装された可能性もありますが、効率性に関心があり、人々がメソッドを直接参照できるようにしたかったのです。したがって、代わりに、ラムダを静的メソッドであるかどうかに関係なく(this
がキャプチャされるかどうかに応じて)プライベートメソッドに変換し、 メタファクトリを使用します 実際のラムダオブジェクトを作成し、プライベートメソッドの実際のコードに転送します。
詳細については、 次のページを参照してください。
Collectionインターフェースに、ストリームを返すstream()
メソッドを実装するデフォルトのメソッドが追加されました。デフォルトのメソッドは、Java 8の新機能であり、APIを進化させるためにインターフェースがメソッドを実装できるようにします。そのため、コレクションのstream()
メソッドのこの実装は、 Streamインターフェイスを実装し、それを返すオブジェクト。
内部的に、Collectionインターフェイスメソッドstream()
は、ドキュメント化されているStreamSupportクラスへの呼び出しを転送します。 SteamSupportクラスは、次に、JavaソースコードJava 8 JDKにある)にあるReferencePipelineと呼ばれるドキュメント化されていないクラスを構築します。
したがって、APIデザイナーの意図は、カスタムストリームを実行したい場合は、StreamSupportクラス以外に進めないことです。