web-dev-qa-db-ja.com

Stream.filter()メソッドはどのように機能しますか?

私はラムダ式がどのように機能するかを知っており、それがフィルタリングする基準を確立するのが.filter()の引数であることを知っています。しかし、.filter()が引数を使用する方法(この場合はラムダ式)がわかりません。filter()には実装がないか、少なくともコンパイル時に実装が必要なためです。私はOracleのサイトでこの未知の実装を検索しましたが、それがどのように機能するかを説明する数語しかなく、コードはまったくありません。

その実装は非表示ですか、Javaコンパイラによって自動的に作成されますか?

集約操作には1つ必要ですか?

double average = roster
  .stream()
  .filter(p -> p.getGender() == Person.Sex.MALE)
  .mapToInt(Person::getAge)
  .average()
  .getAsDouble();

rosterList<Person>ArrayList<Person>インスタンスです

Personは人を表す単純なクラスです

2
user3727894

ラムダオブジェクトは、コンパイラによって自動的に作成されます。

「機能的な」インターフェース(つまり、機能が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がキャプチャされるかどうかに応じて)プライベートメソッドに変換し、 メタファクトリを使用します 実際のラムダオブジェクトを作成し、プライベートメソッドの実際のコードに転送します。

詳細については、 次のページを参照してください。

1
ratchet freak

Collectionインターフェースに、ストリームを返すstream()メソッドを実装するデフォルトのメソッドが追加されました。デフォルトのメソッドは、Java 8の新機能であり、APIを進化させるためにインターフェースがメソッドを実装できるようにします。そのため、コレクションのstream()メソッドのこの実装は、 Streamインターフェイスを実装し、それを返すオブジェクト。

内部的に、Collectionインターフェイスメソッドstream()は、ドキュメント化されているStreamSupportクラスへの呼び出しを転送します。 SteamSupportクラスは、次に、JavaソースコードJava 8 JDKにある)にあるReferencePipelineと呼ばれるドキュメント化されていないクラスを構築します。

したがって、APIデザイナーの意図は、カスタムストリームを実行したい場合は、StreamSupportクラス以外に進めないことです。

0
user154950