狠狠撸
Search
Submit Search
きつねさんと学ぶ Lambda式&StreamAPIハンズオン[関ジャバ2015/7/11] #kanjava
?
5 likes
?
1,395 views
B
bitter_fox
きつねさんと学ぶ Lambda式&StreamAPIハンズオン
Read less
Read more
1 of 94
Download now
Download to read offline
More Related Content
きつねさんと学ぶ Lambda式&StreamAPIハンズオン[関ジャバ2015/7/11] #kanjava
1.
きつねさんと学ぶ Lambda式&StreamAPIハンズオン 2015/7/11 @ 関ジャバ
2.
2 Who are you? 吉田真也(@bitter_fox,
@shinyafox) ● 立命館大学 情報理工学部 情報システム学科 – 高性能計算機ソフトウェアシステム研究室 ● 立命館コンピュータクラブ(RCC) ● http://www.rcc.ritsumei.ac.jp/ ● OpenJDKコミッタ – Project Kulla
3.
3 Project Kulla
4.
ハンズオンの诸注意
5.
1.わからないことがあったら TAさんを呼んでください
7.
2.滨顿贰の自动変换机能禁止
8.
3.本ハンズオンでは メソッド参照は使用しません
9.
Main1 ラムダ式導入 匿名クラスで書かれたコードを ラムダ式で置き換えてみましょう
10.
ラムダ式 ● 関数型インターフェースを実装&インスタンス化 する – メソッドが一つのインターフェース –
Runnable, Function<T>, etc... ● (引数) -> {文} ● (引数) -> 式
11.
Main2 関数型インターフェース 自分で関数型インターフェースを定義してみよう
12.
関数型インターフェース ● メソッドが一つのインターフェース interface F { void
exec0(); } ● @FunctionalInterfaceアノテーション – コンパイル時に関数型インターフェースかを検査
13.
Any question?
14.
Main3 内部イテレーションへ (拡張)for文をIterable#forEachで書き換えよう
15.
Main3 List<Integer>の要素を 一行ずつ出力 for (Integer n
: list) { System.out.println(n); }
16.
外部イテレーション? 内部イテレーション? ● 外部イテレーション – イテレーションをユーザコードが行う – for文,while文 –
並列化が困難 ● ユーザコードの大幅な変更が必要 ● 内部イテレーション – イテレーションをライブラリが行う – イテレーション以外の処理を受け取る – 并列化が容易 ● イテレーションの方法を簡単に切り替えられる ● ユーザコードの変更は最小限
17.
Iterable#forEach list.forEach(n -> System.out.println(n));
18.
Main4 StreamAPI導入 複雑なイテレーションをStreamAPIで書いてみよう
19.
Main4 List<Integer>の 2で割り切れる 要素だけを一行ずつ出力
20.
StreamAPI ● 内部イテレーション&パイプライン化 ● 汎用性高い – あらゆる形式のデータ列に対応可 ●
Collection ● 値の範囲 ● 任意の値 – データ列自体は保持していない ● データへのアクセス手段を保持
21.
21 StreamAPI java.util.stream. Stream<T> IntStream LongStream DoubleStream – ソースから生成される – 中間操作と终端操作でデータを弄る –
并列化が容易
22.
22 Collection 配列 BufferReader etc... Stream IntStream LongStream DoubleStream 中間操作 终端操作 j.u.stream.*Source
23.
23 中間操作? ● Stream#filterやmapなど – Streamを返すメソッド ● 终端操作が行われるまで処理されない –
遅延される
24.
24 终端操作? ● Stream#forEachやreduceやcollectなど – Streamを返さないメソッド ● 遅延されていた中間操作を確定 –
1回のループで済む
25.
25 StreamAPIで書くポイント ● ソース,中間操作,终端操作を意識する ● forEachで副作用を与えて何でも書こうとしない – forEachを使わずに実現する方法が存在する(はず) –
出力などの副作用は翱碍
26.
Main4(再掲) List<Integer>の 2で割り切れる 要素だけを一行ずつ出力
27.
Main4 List<Integer>の ソース 2で割り切れる filter[中間操作] 要素だけを一行ずつ出力
蹿辞谤贰补肠丑摆终端操作闭
28.
Collection<T>からStream<T> ● Collection<T>#stream() – parallelStream()で並列Streamも取得可
29.
29 filter[中間] ● filter(T ->
boolean) – フィルタリング – 各要素を引数に適用しtrueを返したもののみ残す – filterの引数には欲しい値の条件を書く – s.filter(Objects::nonNull) // nullを除外 Stream<T> IntStream LongStream DoubleStream
30.
Main5 値の変換を行う中間操作をしてみよう
31.
Main5 List<Person>から Personの名前を 一行ずつ出力
32.
Main5 List<Person>から ソース Personの名前を map[中間操作] 一行ずつ出力
蹿辞谤贰补肠丑摆终端操作闭
33.
33 map[中間操作] ● map(T ->
R) – 写像?変換 – 各要素を引数に適用した結果のStreamを作る – personStream.map(p -> p.getName()) – seq.map(n -> n * 2) Stream<T> IntStream LongStream DoubleStream
34.
34 Streamを横断するmap Stream<T> IntStream LongStream DoubleStream #mapToObj #mapToInt #mapToLong #mapToDouble #mapToDouble #mapToLong #mapToInt
35.
Main6 複数の要素から一つの値へ
36.
Main6 ある数値の範囲の 総和を求める 乱数生成器Randomから 指定された個数の数値の 平均を求める
37.
Main6 ある数値の範囲の ソース 総和を求める 终端操作 乱数生成器Randomから
ソース 指定された個数の数値の 中間操作 平均を求める 终端操作
38.
値の範囲からStream ● IntStream.range(start, end) –
start?end(end含まない)のIntStream – end含める場合はrangeClosed
39.
39 reduce[終端] ● Optional<T> reduce((T,
T) -> T) ● T reduce(T, (T, T) -> T) ● U reduce(U, (U, T) -> U, (U, U) -> U) – 集約 – s.reduce((n, m) -> n < m ? n : m) ● Optional – 値が無いという状態を表すことができる Stream<T> IntStream LongStream DoubleStream
40.
40 reduce[終端]
41.
41 reduce[終端]
42.
42 reduce[終端]
43.
43 reduce[終端]
44.
44 reduce[終端]
45.
45 reduce[終端]
46.
46 並列reduce
47.
47 並列reduce
48.
48 並列reduce
49.
49 並列reduce
50.
50 並列reduce
51.
51 並列reduce 6
52.
52 並列reduce 6
53.
53 sum[終端] ● int sum() ●
long sum() ● double sum() – 総和を求める ● そのものズバリ – s.sum() Stream<T> IntStream LongStream DoubleStream
54.
54 summaryStatistics[終端] ● XxxSummaryStatistics summaryStatistics() – 統計処理 ● 合計,平均,最大,最小,個数 –
stream.summaryStatistics().getSum() – 複数の統計的な値を求める場合 Stream<T> IntStream LongStream DoubleStream
55.
Main6 ある数値の範囲の ソース 総和を求める 终端操作 乱数生成器Randomから
ソース 指定された個数の数値の 中間操作 平均を求める 终端操作
56.
56 RandomからStream ● Random#doubles() – DoubleStream –
無限のStream – limitと併用 ● Random#doubles(n) – n個の要素のDoubleStream
57.
57 Ave, max, min[終端] ●
average(), max(), min() – Optional系を返す – 平均,最大,最小値を求める Stream<T> IntStream LongStream DoubleStream
58.
Main6_1 Streamと並列処理
59.
59 Change the type
of Stream Sequential Stream Parallel Stream parallel() sequential()
60.
60 Streamと並列処理 ● 並列化したら早くなるのか – 一概には言えない??? ● データ数依存 ● CPU依存 ● 操作依存 –
早くなるものもある – 並列化に際してはベンチマーク必須
61.
Any question?
62.
Main7 ファイルからの読み出しと リストへの集約
63.
Main7 ファイルから “{“か”}”で終わる行を 出力する ファイルから “{“か”}”で終わる行を リストに入れる
64.
Main7 ファイルから “{“か”}”で終わる行を 出力する ファイルから “{“か”}”で終わる行を リストに入れる
65.
Main7 ファイルから ソース “{“か”}”で終わる行を 中間操作 出力する
终端操作 ファイルから ソース “{“か”}”で終わる行を 中間操作 リストに入れる 终端操作
66.
ファイルからStream<String> ● BufferedReader#lines() ● j.nio.file.Files#lines(Path) –
一行ずつのStream – Closeしなければいけない ● twr利用可 try (Stream<String> lines = Files.lines(path)) { }
67.
Main7 ファイルから ソース “{“か”}”で終わる行を 中間操作 出力する
终端操作 ファイルから ソース “{“か”}”で終わる行を 中間操作 リストに入れる 终端操作
68.
68 collect ● R collect(()
-> R, (R, T) -> R, (R, R) -> void) ● R collect(Collector<T, ?, R>) – 集約処理 – R:集約先のオブジェクト – () -> R:集約先のオブジェクトの生成 – (R, T) -> R:集約先のオブジェクトRに要素Tを集約 – (R, R) -> void:集約先のオブジェクトR同士のcombine ● 並列処理用
69.
69 Collectors#toXxx ● toCollection() ● toList() ●
toSet() – リストなどへの集約をするCollectorの生成
70.
Main8 Streamを返す変換を平坦化する
71.
Main8 List<Campany>から List<Car>を取得し すべての車のうちの 軽自動車のみの 車名の リストを作る
72.
Main8 List<Campany>から ソース List<Car>を取得し 中間操作 すべての車のうちの 軽自動車のみの
filter 車名の map リストを作る collect(toList())
73.
Streamを返すmap H e l
l H e l l o H e l l o , W H e l Stream<Stream<R>>Stream<T>
74.
flatMap H e l
l H e l l o H e l l o , W H e l Stream<R>Stream<T>
75.
flatMap ● flatMap(T ->
Stream<R>) – 写像?変換 + 平坦化 – 平坦化されたStream<R> – companieStream.flatMap(c → c.getList().stream())
76.
Main9 文字列の連結
77.
Main9 List<Person>から Personの名前を ,区切りで連結する
78.
Main9 List<Person>から ソース Personの名前を 中間操作 ,区切りで連結する
终端操作
79.
79 Collectors#joining ● joining() ● joining(delimiter) ●
joining(delimiter, prefix, suffix) – 文字列の連結をするCollectorを返す – 単なる連結だけでなく,デリミタなども指定可
80.
Main10 同じ値でグループ化
81.
Main10 List<People>から 同じ性別でPeopleをグループ化 List<People>から 同じ名字でPeopleの名前をグループ化
82.
82 Collectors#groupingBy ● groupingBy(T ->
K) – Kの同じ値でグループ化 – Map<K, List<T>>にする
83.
83 Collectors#groupingBy ● groupingBy(T ->
K, Collector) – 第二引数はMapの値へのCollector – groupingBy(..., toSet()) : Map<K, Set<T>>
84.
84 Collectors#mapping ● mapping(T ->
U, Collector) – 値の変換を行って集約するCollector
85.
Main10_1 並列グループ化
86.
groupingBy vs. groupingByConcurrent ● groupingByでも並列化できる –
分割統治法 – Map<K, List<V>>同士の連結が起きる ● 逐次よりも遅くなる可能性 ● groupingByConcurrent – 一つのMap<K, List<V>>にマルチスレッドでアクセス – 中間操作は並列 ● 中間操作があれば逐次よりも高速に ● どちらが良いかは,場合による
87.
87 Parallel groupingBy H e l
l o , W o r l d !
88.
88 Parallel groupingBy Split!!
89.
89 Parallel groupingBy Map Map Map
Map
90.
90 Parallel groupingBy Map Map Map
MapMap Map
91.
91 Parallel groupingBy Map MapMap Map
92.
92 Parallel groupingBy Map Map
93.
93 H e l
o , W o r l d ! Map parallel groupingByConcurrent
94.
Any question?
Download