Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
JavaのStreamで学ぶ
遅延処理実装パターン
@mike_neck
ことわり
渋谷Javaの日程を間違えて、先週に資料上げてる
から、内容を皆さんもうご存知なので、雑にやりま
す
概要
Streamの復習
Streamについての疑問
Streamパイプラインがやっていること
Sinkの合成
終端操作と処理開始
誰?
持田真哉(@mike_neck)
たんなるJava、Groovy好きのおっさん
某IDEを売っている会社に入り浸って、クソコラを作ってる
2015年期待している陸上選手
青山聖佳(400m)、水口怜(走幅跳)、藤光謙司(200m)、
高瀬...
Streamの復習
for文を簡単に今っぽく書くやつ
InputStreamと関係ない(全く関係ないわけで
もないけど)
ScalaのStreamとは違う
順次および並列での集約操作をサポートする要素の
シーケンス(Javadocより)
Streamの復習
repo.findAllUsers().stream()
.filter(User::isMen)
.filter(u -> u.getAge() >= 27)
.filter(u -> u.getAge() <= 35)
...
Streamの疑問
repo.findAllUsers().stream()
.filter(User::isMen)
.filter(u -> u.getAge() >= 27)
.filter(u -> u.getAge() <= 35)
...
Streamパイプラインがやってい
ること
repo.findAllUsers().stream()
.filter(User::isMen)
.filter(u -> u.getAge() >= 27)
.filter(u -> u.getA...
Streamパイプラインがやってい
ること
.filter(User::isMen) AbstractPipeline
User:isMen
Streamパイプラインがやってい
ること
.filter(User::isMen)
.map(User::getHobbies)
AbstractPipeline
AbstractPipeline
User:isMen
User::getHo...
Streamパイプラインがやってい
ること
.filter(User::isMen)
.map(User::getHobbies)
.flatMap(List::stream)
AbstractPipeline
AbstractPipeline...
Streamパイプラインがやってい
ること
.filter(User::isMen)
.map(User::getHobbies)
.flatMap(List::stream)
AbstractPipeline
AbstractPipeline...
public final <R> Stream map(
Function<? super P_OUT, ? extends R> mapper) {
return
new StatelessOp<P_OUT, R>(this, …) {
@O...
public final <R> Stream map(
Function<? super P_OUT, ? extends R> mapper) {
return
new StatelessOp<P_OUT, R>(this, …) {
@O...
public final <R> Stream map(
Function<? super P_OUT, ? extends R> mapper) {
return
new StatelessOp<P_OUT, R>(this, …) {
@O...
Sinkの合成
Sink<T>とは
個々の処理実行・制御を提供するConsumer<T>
の拡張インターフェース
初期状態 ! begin(long) ! 処理中 !
accept(T) ! 処理中 ! end() ! 初期状態
後方へのリンク...
Sinkの合成
ChainedReference
<B, A> implements
Sink<A>
ChainedReference
<C, B> implements
Sink<B>
begin(long) begin(long)
acce...
Sinkの合成
ChainedReference
<B, A> implements
Sink<A>
ChainedReference
<C, B> implements
Sink<B>
begin(long) begin(long)
acce...
Sinkの合成
ChainedReference
<B, A> implements
Sink<A>
ChainedReference
<C, B> implements
Sink<B>
begin(long) begin(long)
acce...
仕組みはわかったけど、
Sinkの合成はいつやるん?
終端操作と処理開始
一番最後にあるSinkは終端操作TerminalOp<T,
R>にて生成されるTerminalSink<T, R>
終端操作はAbstractPipelineの逆順リストをた
どってSinkを合成していく
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
Element
Element
Elemen...
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
Element
Element
Elemen...
終端操作と処理開始
AbstractPipeline
AbstractPipeline
AbstractPipeline
Sink
Sink
Sink
TerminalOp
TerminalSink
Element
Element
Elemen...
まとめ
ストリームパイプラインはStreamを実装した無名クラ
スのインスタンスの逆順リストを作る
StreamのopWrapSinkに各処理
(Function,Predicate)が埋め込まれる
処理順リストによって処理順序を保証
終端操作...
以下、応用
• Java8の目玉機能といえば…
Optionalですね
Optionalの操作順序
• Javaらしく正格に実行されます
今のStreamの実装パターンを
もってLazyなOptional作れな
いか?
というわけで作っときました
• 無駄にLazyなOptional
• https://gist.github.com/mike-neck/
ebb6e1b170f8db8250f8
おわり
(最後は雑にまとめた)
で検索🔎mike-neck Stream
Nächste SlideShare
Wird geladen in …5
×

JavaのStreamで学ぶ遅延処理実装パターン

4.300 Aufrufe

Veröffentlicht am

JavaのStreamで必要になった時だけに処理を行うようなプログラミングパターンを学ぶ

Veröffentlicht in: Technologie
  • Loggen Sie sich ein, um Kommentare anzuzeigen.

JavaのStreamで学ぶ遅延処理実装パターン

  1. 1. JavaのStreamで学ぶ 遅延処理実装パターン @mike_neck
  2. 2. ことわり 渋谷Javaの日程を間違えて、先週に資料上げてる から、内容を皆さんもうご存知なので、雑にやりま す
  3. 3. 概要 Streamの復習 Streamについての疑問 Streamパイプラインがやっていること Sinkの合成 終端操作と処理開始
  4. 4. 誰? 持田真哉(@mike_neck) たんなるJava、Groovy好きのおっさん 某IDEを売っている会社に入り浸って、クソコラを作ってる 2015年期待している陸上選手 青山聖佳(400m)、水口怜(走幅跳)、藤光謙司(200m)、 高瀬慧(100m)
  5. 5. Streamの復習 for文を簡単に今っぽく書くやつ InputStreamと関係ない(全く関係ないわけで もないけど) ScalaのStreamとは違う 順次および並列での集約操作をサポートする要素の シーケンス(Javadocより)
  6. 6. Streamの復習 repo.findAllUsers().stream() .filter(User::isMen) .filter(u -> u.getAge() >= 27) .filter(u -> u.getAge() <= 35) .map(User::getHobbies) .flatMap(List::stream) .collect(groupingBy( Hobby::getGenre, counting())); ソース ストリームパイプライン 終端操作
  7. 7. Streamの疑問 repo.findAllUsers().stream() .filter(User::isMen) .filter(u -> u.getAge() >= 27) .filter(u -> u.getAge() <= 35) .map(User::getHobbies) .flatMap(List::stream) .collect(groupingBy( Hobby::getGenre, counting())); ・これらの処理はどのように保持 されるの? ・処理の順番はどのように保持さ れるの? ・終端操作呼び出しでどのように 処理が実行されるの?
  8. 8. Streamパイプラインがやってい ること repo.findAllUsers().stream() .filter(User::isMen) .filter(u -> u.getAge() >= 27) .filter(u -> u.getAge() <= 35) .map(User::getHobbies) .flatMap(List::stream) .collect(groupingBy( Hobby::getGenre, counting())); ・AbstractPipeline<P_IN, P_OUT, Stream<P_OUT>>のイ ンスタンスを生成して返す
  9. 9. Streamパイプラインがやってい ること .filter(User::isMen) AbstractPipeline User:isMen
  10. 10. Streamパイプラインがやってい ること .filter(User::isMen) .map(User::getHobbies) AbstractPipeline AbstractPipeline User:isMen User::getHobbies
  11. 11. Streamパイプラインがやってい ること .filter(User::isMen) .map(User::getHobbies) .flatMap(List::stream) AbstractPipeline AbstractPipeline AbstractPipeline User:isMen User::getHobbies List::stream
  12. 12. Streamパイプラインがやってい ること .filter(User::isMen) .map(User::getHobbies) .flatMap(List::stream) AbstractPipeline AbstractPipeline AbstractPipeline User:isMen User::getHobbies List::stream AbstractPipelineの逆順リストを作っている
  13. 13. public final <R> Stream map( Function<? super P_OUT, ? extends R> mapper) { return new StatelessOp<P_OUT, R>(this, …) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { public void accept(P_OUT u) {downSink.accept(mapper.apply(u));} } Streamパイプラインがやってい ること 返されるStreamの無名クラスの中の opWrapSinkメソッドに埋め込まれる
  14. 14. public final <R> Stream map( Function<? super P_OUT, ? extends R> mapper) { return new StatelessOp<P_OUT, R>(this, …) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { public void accept(P_OUT u) {downSink.accept(mapper.apply(u));} }
  15. 15. public final <R> Stream map( Function<? super P_OUT, ? extends R> mapper) { return new StatelessOp<P_OUT, R>(this, …) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { public void accept(P_OUT u) {downSink.accept(mapper.apply(u));} } Sinkの合成
  16. 16. Sinkの合成 Sink<T>とは 個々の処理実行・制御を提供するConsumer<T> の拡張インターフェース 初期状態 ! begin(long) ! 処理中 ! accept(T) ! 処理中 ! end() ! 初期状態 後方へのリンクを持つリスト
  17. 17. Sinkの合成 ChainedReference <B, A> implements Sink<A> ChainedReference <C, B> implements Sink<B> begin(long) begin(long) accept(a) accept(b) end() end() a -> b b -> c ・先に行われる処理(Sink)は次 に行われる処理(Sink)へのリン クを持っている
  18. 18. Sinkの合成 ChainedReference <B, A> implements Sink<A> ChainedReference <C, B> implements Sink<B> begin(long) begin(long) accept(a) accept(b) end() end() a -> b b -> c ・accept(A)は処理を施した後に次の処 理(Sink)のaccept(B)を呼び出す
  19. 19. Sinkの合成 ChainedReference <B, A> implements Sink<A> ChainedReference <C, B> implements Sink<B> begin(long) begin(long) accept(a) accept(b) end() end() a -> b b -> c Sinkがリンクドリストになっていること で処理順を保持している
  20. 20. 仕組みはわかったけど、 Sinkの合成はいつやるん?
  21. 21. 終端操作と処理開始 一番最後にあるSinkは終端操作TerminalOp<T, R>にて生成されるTerminalSink<T, R> 終端操作はAbstractPipelineの逆順リストをた どってSinkを合成していく
  22. 22. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink
  23. 23. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink
  24. 24. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink
  25. 25. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink
  26. 26. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink
  27. 27. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink Element Element Element Element
  28. 28. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink Element Element Element Element
  29. 29. 終端操作と処理開始 AbstractPipeline AbstractPipeline AbstractPipeline Sink Sink Sink TerminalOp TerminalSink Element Element Element Element
  30. 30. まとめ ストリームパイプラインはStreamを実装した無名クラ スのインスタンスの逆順リストを作る StreamのopWrapSinkに各処理 (Function,Predicate)が埋め込まれる 処理順リストによって処理順序を保証 終端操作で逆順Streamインスタンスを って処理を合 成、ソースを順次適用
  31. 31. 以下、応用 • Java8の目玉機能といえば…
  32. 32. Optionalですね
  33. 33. Optionalの操作順序 • Javaらしく正格に実行されます
  34. 34. 今のStreamの実装パターンを もってLazyなOptional作れな いか?
  35. 35. というわけで作っときました • 無駄にLazyなOptional • https://gist.github.com/mike-neck/ ebb6e1b170f8db8250f8
  36. 36. おわり (最後は雑にまとめた) で検索🔎mike-neck Stream

×