SlideShare una empresa de Scribd logo
1 de 67
Java 8 勉強会
怖くない!ラムダ式, Stream API
2015/09/30 株式会社デーコム Ken
自己紹介
 名前
 Ken
 所属
 株式会社デーコム (4年目)
 やってること
 Webアプリの実装
 Java, SAStruts
 Javascript, CSS3
 jQuery, flotr2(グラフ表示)
 SPARQL (sqlっぽいやつ)
 今熱いこと
 数学, 哲学
 『数学ガール』(結城浩) とか
 コンピュータ将棋(電王戦)
自己紹介 – つづき
 趣味とか
 趣味プログラミング(まれに)
 なぞぷよ, 2chブラウザ, ルービックキューブ用タイマーなど
 音ゲー
 beatmaniaIIDX 全曲ハードクリア(未解禁曲以外)
 Dance Dance Revolution 足鳳凰
 Splatoon
 ウデマエ S, 最近のブキ:ノヴァブラスターネオ
 タイムアタック
 ルービックキューブ (自己べ22秒, 最近は40秒)
 海腹川背, 星のカービィSDX, ロックマンX4
勉強会のtarget
 Java 6,7の知識で止まっている方
 ラムダ式、あぁあの 気持ち悪い やつね という方
 StreamAPI、って何だ という方
Java 8の新機能のうち、今回話さないこと
 話さないこと
 Stream API の parallel()
 (使ったことない & 排他など複雑なので)
 Optional
 (準備できませんでした)
 DateTime API
 デフォルトメソッド
 など...
前提知識
 Java 6
 interface
 匿名クラス
 ジェネリクス
ラムダ式 (Lambda Expression)
舎 λ λ λ λ.....
x -> x * 2
ラムダ式
 x -> x * 2
 x を引数に取って、x * 2 を返す
 メソッドとして考えると
 int convert(int x) {
return x * 2;
}
 JavaScriptなら
 function(x){
return x * 2;
}
ありそうな例
ラムダ式 - ありそうな例
 人を表すクラス
 class Person {
String name;
int age;
}
ラムダ式 - ありそうな例
 20歳以上の人だけ処理する
 public void main(){
method(list, 20);
}
 void method (List<Person> list, int minAge) {
for(Person p : list) {
if(p.age >= minAge)
doSomething(p);
}
}
ラムダ式 - ありそうな例
 6歳以上12歳以下の人だけを処理する
 public void main(){
method(list, 6, 12);
}
 void method (List<Person> list, int minAge, int maxAge) {
for(Person p : list) {
if(p.age >= minAge && p.age <= maxAge)
doSomething(p);
}
}
ラムダ式 - ありそうな例
 名前が「A」で始まる人だけを処理する
 public void main(){
method(list, 0, 999, “A”);
}
 void method (List<Person> list, int minAge, int maxAge,
String nameStartWith) {
for(Person p : list) {
if(p.age >= minAge &&
p.age <= maxAge &&
p.name.startWith(nameStartWith))
doSomething(p);
}
}
ラムダ式 - ありそうな例
 名前が「B」で終わる人だけを処理
 年齢が偶数の人だけを処理
 名前の文字数が10以上の人だけを処理
・
・
・
_人人人人人人_
> 引数地獄 <
 ̄Y^Y^Y^Y^Y ̄
ラムダ式 – ありそうな例
 interfaceを導入する
 interface PersonFilter {
/**
* pをフィルタに通過させる場合はtrueを返します。
*/
boolean test(Person p);
}
ラムダ式 – ありそうな例
 メソッド呼び出し側でフィルタ条件のプログラムを
書く (匿名クラスを利用)
 public void main(){
method(list, new PersonFilter(){
boolean test(Person p) {
return p.age >= 20;
}
});
}
 void method(List<Person> list, PersonFilter filter) {
for(Person p : list) {
if(filter.test(p)) {
doSomething(p);
}
}
}
ラムダ式 – ありそうな例
 メソッド呼び出し側でフィルタ条件のプログラムを
書く (匿名クラスを利用)
 public void main(){
method(list, new PersonFilter(){
boolean test(Person p) {
return p.age >= 20;
}
});
}
 void method(List<Person> list, PersonFilter filter) {
for(Person p : list) {
if(filter.test(p)) {
doSomething(p);
}
}
}
絞り込み条件を変更しても
処理する側は変更なし
ラムダ式 – ありそうな例
 匿名クラスの記法は無駄が多い(定型文が多い)
 method(list, new PersonFilter(){
boolean test(Person p) {
return p.age >= 20;
}
});
ラムダ式 – ありそうな例
 匿名クラスの記法は無駄が多い(定型文が多い)
 method(list, new PersonFilter(){
boolean test(Person p) {
return p.age >= 20;
}
});
やりたいこと
定型文
ラムダ式
ラムダ式 – ありそうな例
 ラムダ式を使った記法
 method(list, p -> p.age >= 20);
ラムダ式 – ありそうな例
 ラムダ式を使った記法
 method(list, p -> p.age >= 20);
アロー演算子
(ハイフン+大なり)
ラムダ式 – ありそうな例
 ラムダ式を使った記法
 method(list, p -> p.age >= 20);
引数 返す値
ラムダ式 – ありそうな例
 ラムダ式 = 匿名クラスの省略記法
 匿名クラス
 new PersonFilter(){
boolean test(Person p) {
return p.age >= 20;
}
});
 ラムダ式
 p -> p.age >= 20
ラムダ式 – ありそうな例
 省略しない書き方
 method(list,(Person p) -> { return p.age >= 20;});
引数 処理
ラムダ式 – ありそうな例
 省略しない書き方
 method(list,(Person p) -> { return p.age >= 20;});
引数の型が推測可能
な場合は不要
ラムダ式 – ありそうな例
 省略しない書き方
 method(list, (p) -> { return p.age >= 20;});
引数1個なら
カッコは不要
ラムダ式 – ありそうな例
 省略しない書き方
 method(list, p -> { return p.age >= 20;});
単に値を返すだけなら
式だけを書けばOK
ラムダ式 – ありそうな例
 省略しない書き方
 method(list, p -> p.age >= 20);
 ↑同じ!↓
 method(list,(Person p) -> { return p.age >= 20;});
ラムダ式 – 記法の例
 引数0個
 () -> 1
 引数1個
 (x) -> x * 2
 x -> x * 2
 引数1個の場合のみ引数のカッコを省略できる
 引数2個
 (a, b) -> a - b
他の例
ラムダ式 – 他の例
 Android とか (イベントドリブンでよく見かけるパター
ン)
 Buttonがクリックされたときの処理を設定する
 匿名クラス
 button.addOnClickListener(new OnClickListener(){
void onClick() {
doSomething();
}
});
 ラムダ式
 button.addOnClickListener( () -> {
doSomething();
});
ラムダ式 – 他の例
 Android とか (イベントドリブンでよく見かけるパター
ン)
 Buttonがクリックされたときの処理を設定する
 匿名クラス
 button.addOnClickListener(new OnClickListener(){
void onClick() {
doSomething();
}
});
 ラムダ式
 button.addOnClickListener( () -> {
doSomething();
});
・行数が少ない
・インデントが浅い
関数型interface
どんなinterfaceにもラムダ式を渡せるの?
 引数の型が「関数型interface」の条件を満たしてい
る場合だけ
 ≒ メソッド数が1個のinterfaceのこと
 例外: デフォルトメソッドはあってもいい etc...
 interface Example {
// メソッド1個なので関数型interface
void hoge ();
}
@FunctionalInterface アノテーション
 interfaceが関数型interfaceであると宣言するアノテー
ション
 これを付けると「関数型interface」の条件を満たさない
ときにコンパイルエラーにしてくれる
 付けなくても条件を満たせば関数型interfaceになる
 @FunctionalInterface
interface InvalidExample {
// メソッド2個なので関数型interfaceではない
// コンパイルエラー
void methodA();
void methodB();
}
標準の関数型interface
ラムダ式 – 標準の関数型interface
 例ではこのようなinterfaceを自分で定義した
 interface PersonFilter {
/**
* pをフィルタに通過させる場合はtrueを返します。
*/
boolean test(Person p);
}
 よく使うinterfaceが標準で定義されている
 interface Predicate<T> {
boolean test(T elem);
// 実際にはもうちょっと複雑な定義
}
ラムダ式 – 標準の関数型interface
 標準の関数型interfaceを使う場合
 public void main(){
method(list, p -> p.age >= 20);
}
 void method(List<Person> list, Predicate<Person> filter) {
for(Person p : list) {
if(filter.test(p)) {
doSomething(p);
}
}
}
ラムダ式 – 標準の関数型interface
 いろいろある
 引数なし, 戻り値なし
 Runnable
 引数なし, 戻り値T
 Supplier<T>
 引数T, 戻り値なし
 Consumer<T>
 引数T, 戻り値U
 Function<T, U>
 引数T, 戻り値boolean
 Predicate<T>
 ほかに30種類くらいあります
メソッド参照
 interfaceのメソッドと同じシグネチャを持つメソッ
ドがあれば、メソッド自体を引数で渡せる
 ラムダ式
 button.addOnClickListener(() -> {doSomething();});
 メソッド参照
 button.addOnClickListener(this::doSomething);
 コロン2個の後にメソッド名
 ラムダ式よりもコードが短くなる
 引数リストが隠れるのでわかりづらくなる場合がある
Stream API
Stream API の導入 – for文からの変換
 5文字より長い文字列を大文字に変換して処理を行う
 for(String s : list) {
if (s.length() > 5) {
String upper = s.toUpperCase();
method(upper);
}
}
Stream API の導入 – for文からの変換
 5文字より長い文字列を大文字に変換して処理を行う
 for(String s : list) {
if (s.length() > 5) {
String upper = s.toUpperCase();
method(upper);
}
}
絞り込み
(filter)
Stream API の導入 – for文からの変換
 5文字より長い文字列を大文字に変換して処理を行う
 for(String s : list) {
if (s.length() > 5) {
String upper = s.toUpperCase();
method(upper);
}
}
変換
(map : 写像)
Stream API の導入 – for文からの変換
 5文字より長い文字列を大文字に変換して処理を行う
 for(String s : list) {
if (s.length() > 5) {
String upper = s.toUpperCase();
method(upper);
}
}
順次処理
(for each)
Stream API の導入 – for文からの変換
 5文字より長い文字列を大文字に変換して処理を行う
 for(String s : list) {
filter (5文字より長い)
map (大文字に変換)
forEach (methodで処理)
}
Stream API の導入
 Stream APIによる記法
 list.stream()
.filter( s -> s.length() > 5)
.map( s -> s.toUpperCase())
.forEach( s -> {method(s);} );
Stream API の導入
 Stream APIによる記法
 list.stream()
.filter( s -> s.length() > 5)
.map( s -> s.toUpperCase())
.forEach( s -> {method(s);} );
メソッドチェイン
(4行で1文)
Stream API の導入
 Stream APIによる記法
 list.stream()
.filter( s -> s.length() > 5)
.map( s -> s.toUpperCase())
.forEach( s -> {method(s);} );
 for(String s : list) {
if (s.length() > 5) {
String upper = s.toUpperCase();
method(upper);
}
}
しっぽが無い
Stream API のメソッド
Stream API のメソッド - Streamの始め方
 ListからStreamを作成する
 List list = new ArrayList(Arrays.asList(“a”, “b”, “c”));
list.stream()
 配列からStreamを作成する
 String[] array = {“a”, “b”, “c”};
Arrays.stream(array)
 整数を列挙したStreamを作成する
 IntStream.range(0, 10)
 for(int i=0; i<10; i++) と同じ
 IntStream.rangeClosed(0, 10)
 for(int i=0; i<=10; i++) と同じ
 テキストファイルなどから
 BufferedReader br = /*省略*/;
br.lines()
 1行ぶんの文字列を1要素としたStreamになる
Stream API のメソッド – Streamに対する処理
 中間処理と終端処理がある
 中間処理
 Streamの要素を変化させる
 戻り値はStream
 メソッドチェインで処理が継続
 終端処理
 Streamの要素を使って
最終的な結果を得る or 処理を行う
 戻り値は void とか 要素の型 とか boolean とか
Stream API のメソッド – 中間処理
 filter (Predicate<T>)
 Streamの要素を絞り込む
 map (Function<T, U>)
 Streamの要素を変換する
 別の型に変えてもok
 .map(p -> p.name) とか(Person → String)
 skip (long n)
 Streamの最初のn個の要素を飛ばす
 peek (Consumer<T>)
 各要素を処理する。forEachに似ているが、Streamを継続できる点で異
なる
 デバッグ用
 list.stream().peek( s -> {log.debug(s);}).…
 etc.
Stream API のメソッド – 終端処理
 forEach (Consumer<T>)
 各要素を処理する
 拡張for文とほぼ同じ使い方
 for( String s : list) { }
 list.stream().forEach( s -> { });
 anyMatch (Predicate<T>)
allMatch(Predicate<T>)
 条件に一致する要素が存在するか / 全て一致するか を
booleanで返す
 collect (Collector)
 Streamの全要素を格納したコレクションを生成して返す
 引数には Collectors.toList() などを渡せる
 etc.
色々な例
Stream API – 他の例
 Listの中身が全て条件を満たすかどうか
 Java 7
 boolean valid = true;
for(Person p : list) {
if( p.age < 18 ){
valid = false;
break;
}
}
 Java 8
 boolean valid = list.stream()
.allMatch( p -> p.age >= 18 );
Stream API – 他の例
 Listの要素を標準出力に表示
 java 7
 for(String s : list) {
System.out.plintln(s);
}
 java 8 (ラムダ式)
 list.stream().forEach(s -> {System.out.println(s);});
 java 8 (メソッド参照)
 list.stream().forEach(System.out::println);
Stream API – 他の例
 Listの要素を絞り込んで新しいListに格納する
 Java 7
 List<String> newList = new ArrayList<>();
for (String s : list) {
if (s.length > 5){
newList.add(s);
}
}
 Java 8
 List<String> newList = list.stream()
.filter( s -> s.length() > 5 )
.collect(Collectors.toList());
Stream API – 他の例
 Listの要素を全て変換する
 List#replaceAll
 (Stream APIではなくListの新メソッド)
 Java 7
 List<String> newList = new ArrayList<>();
for(String s : list) {
newList.add(s.toUpperCase());
}
 Java 8
 list.replaceAll( s -> s.toUpperCase() );
Stream API – 他の例
 Mapの要素を順次処理
 Map#forEach
 (Stream API ではなくMapの新メソッド)
 java 7
 for(String k : map.keySet()){
Object v = map.get(v);
method(k, v);
}
 java 8
 map.forEach( (k, v) -> { method(k, v); } );
まとめ
まとめ
 ラムダ式
 匿名クラスの省略記法
 関数型interfaceを引数にとるメソッドに渡せる
 標準の関数型interfaceをうまく利用したい
 Stream API
 コレクションに新しく用意された便利な操作方法
 Stream生成 → 中間処理*n → 終端処理
 for文やwhile文はだいたいStream APIに書き換えできる
 for文禁止時代の到来
ご清聴ありがとう
ございました
質問&雑談タイム

Más contenido relacionado

La actualidad más candente

from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java心 谷本
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Uehara Junji
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Yoshio Terada
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition心 谷本
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
Java8から始める関数型プログラミング
Java8から始める関数型プログラミングJava8から始める関数型プログラミング
Java8から始める関数型プログラミングstylefreeslide
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLispKent Ohashi
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)x1 ichi
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるShintaro Fukushima
 
15分でざっくり分かるScala入門
15分でざっくり分かるScala入門15分でざっくり分かるScala入門
15分でざっくり分かるScala入門SatoYu1ro
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascriptRyuma Tsukano
 

La actualidad más candente (20)

from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
Thinking in Cats
Thinking in CatsThinking in Cats
Thinking in Cats
 
Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016Java Puzzlers JJUG CCC 2016
Java Puzzlers JJUG CCC 2016
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Editionfrom old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Java8から始める関数型プログラミング
Java8から始める関数型プログラミングJava8から始める関数型プログラミング
Java8から始める関数型プログラミング
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)あなたのScalaを爆速にする7つの方法(日本語版)
あなたのScalaを爆速にする7つの方法(日本語版)
 
Functional Way
Functional WayFunctional Way
Functional Way
 
More C++11
More C++11More C++11
More C++11
 
データサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみるデータサイエンスワールドからC++を眺めてみる
データサイエンスワールドからC++を眺めてみる
 
15分でざっくり分かるScala入門
15分でざっくり分かるScala入門15分でざっくり分かるScala入門
15分でざっくり分かるScala入門
 
C++11
C++11C++11
C++11
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascript
 

Similar a 【java8 勉強会】 怖くない!ラムダ式, Stream API

速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門dcubeio
 
Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perlJiro Nishiguchi
 
Pgunconf14 pg13-psql
Pgunconf14 pg13-psqlPgunconf14 pg13-psql
Pgunconf14 pg13-psqlToshi Harada
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Uehara Junji
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよkoji lin
 
The Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaThe Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaYouhei Nitta
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]Kenji Kazumura
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューAkira Inoue
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展Deep Learning JP
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門Shohei Arai
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義JPCERT Coordination Center
 
PostgreSQLとpython
PostgreSQLとpythonPostgreSQLとpython
PostgreSQLとpythonSoudai Sone
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208atmiya
 
知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能Soudai Sone
 

Similar a 【java8 勉強会】 怖くない!ラムダ式, Stream API (20)

Project lambda
Project lambdaProject lambda
Project lambda
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
ゆるふわJava8入門
ゆるふわJava8入門ゆるふわJava8入門
ゆるふわJava8入門
 
Write good parser in perl
Write good parser in perlWrite good parser in perl
Write good parser in perl
 
Cubby 2006-08-23
Cubby 2006-08-23Cubby 2006-08-23
Cubby 2006-08-23
 
Pgunconf14 pg13-psql
Pgunconf14 pg13-psqlPgunconf14 pg13-psql
Pgunconf14 pg13-psql
 
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)Java One 2012 Tokyo JVM Lang. BOF(Groovy)
Java One 2012 Tokyo JVM Lang. BOF(Groovy)
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
サーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよサーバーサイドでの非同期処理で色々やったよ
サーバーサイドでの非同期処理で色々やったよ
 
The Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE FukuokaThe Why and How of Java8 at LINE Fukuoka
The Why and How of Java8 at LINE Fukuoka
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展[DL輪読会]Control as Inferenceと発展
[DL輪読会]Control as Inferenceと発展
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門
 
Subprocess no susume
Subprocess no susumeSubprocess no susume
Subprocess no susume
 
Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義Javaセキュアコーディングセミナー東京第3回講義
Javaセキュアコーディングセミナー東京第3回講義
 
PostgreSQLとpython
PostgreSQLとpythonPostgreSQLとpython
PostgreSQLとpython
 
Coq 20100208a
Coq 20100208aCoq 20100208a
Coq 20100208a
 
知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能知って得するWebで便利なpostgre sqlの3つの機能
知って得するWebで便利なpostgre sqlの3つの機能
 

Último

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 

Último (9)

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 

【java8 勉強会】 怖くない!ラムダ式, Stream API

  • 1. Java 8 勉強会 怖くない!ラムダ式, Stream API 2015/09/30 株式会社デーコム Ken
  • 2. 自己紹介  名前  Ken  所属  株式会社デーコム (4年目)  やってること  Webアプリの実装  Java, SAStruts  Javascript, CSS3  jQuery, flotr2(グラフ表示)  SPARQL (sqlっぽいやつ)  今熱いこと  数学, 哲学  『数学ガール』(結城浩) とか  コンピュータ将棋(電王戦)
  • 3. 自己紹介 – つづき  趣味とか  趣味プログラミング(まれに)  なぞぷよ, 2chブラウザ, ルービックキューブ用タイマーなど  音ゲー  beatmaniaIIDX 全曲ハードクリア(未解禁曲以外)  Dance Dance Revolution 足鳳凰  Splatoon  ウデマエ S, 最近のブキ:ノヴァブラスターネオ  タイムアタック  ルービックキューブ (自己べ22秒, 最近は40秒)  海腹川背, 星のカービィSDX, ロックマンX4
  • 4. 勉強会のtarget  Java 6,7の知識で止まっている方  ラムダ式、あぁあの 気持ち悪い やつね という方  StreamAPI、って何だ という方
  • 5. Java 8の新機能のうち、今回話さないこと  話さないこと  Stream API の parallel()  (使ったことない & 排他など複雑なので)  Optional  (準備できませんでした)  DateTime API  デフォルトメソッド  など...
  • 6. 前提知識  Java 6  interface  匿名クラス  ジェネリクス
  • 8. x -> x * 2
  • 9. ラムダ式  x -> x * 2  x を引数に取って、x * 2 を返す  メソッドとして考えると  int convert(int x) { return x * 2; }  JavaScriptなら  function(x){ return x * 2; }
  • 11. ラムダ式 - ありそうな例  人を表すクラス  class Person { String name; int age; }
  • 12. ラムダ式 - ありそうな例  20歳以上の人だけ処理する  public void main(){ method(list, 20); }  void method (List<Person> list, int minAge) { for(Person p : list) { if(p.age >= minAge) doSomething(p); } }
  • 13. ラムダ式 - ありそうな例  6歳以上12歳以下の人だけを処理する  public void main(){ method(list, 6, 12); }  void method (List<Person> list, int minAge, int maxAge) { for(Person p : list) { if(p.age >= minAge && p.age <= maxAge) doSomething(p); } }
  • 14. ラムダ式 - ありそうな例  名前が「A」で始まる人だけを処理する  public void main(){ method(list, 0, 999, “A”); }  void method (List<Person> list, int minAge, int maxAge, String nameStartWith) { for(Person p : list) { if(p.age >= minAge && p.age <= maxAge && p.name.startWith(nameStartWith)) doSomething(p); } }
  • 15. ラムダ式 - ありそうな例  名前が「B」で終わる人だけを処理  年齢が偶数の人だけを処理  名前の文字数が10以上の人だけを処理 ・ ・ ・
  • 17. ラムダ式 – ありそうな例  interfaceを導入する  interface PersonFilter { /** * pをフィルタに通過させる場合はtrueを返します。 */ boolean test(Person p); }
  • 18. ラムダ式 – ありそうな例  メソッド呼び出し側でフィルタ条件のプログラムを 書く (匿名クラスを利用)  public void main(){ method(list, new PersonFilter(){ boolean test(Person p) { return p.age >= 20; } }); }  void method(List<Person> list, PersonFilter filter) { for(Person p : list) { if(filter.test(p)) { doSomething(p); } } }
  • 19. ラムダ式 – ありそうな例  メソッド呼び出し側でフィルタ条件のプログラムを 書く (匿名クラスを利用)  public void main(){ method(list, new PersonFilter(){ boolean test(Person p) { return p.age >= 20; } }); }  void method(List<Person> list, PersonFilter filter) { for(Person p : list) { if(filter.test(p)) { doSomething(p); } } } 絞り込み条件を変更しても 処理する側は変更なし
  • 20. ラムダ式 – ありそうな例  匿名クラスの記法は無駄が多い(定型文が多い)  method(list, new PersonFilter(){ boolean test(Person p) { return p.age >= 20; } });
  • 21. ラムダ式 – ありそうな例  匿名クラスの記法は無駄が多い(定型文が多い)  method(list, new PersonFilter(){ boolean test(Person p) { return p.age >= 20; } }); やりたいこと 定型文
  • 23. ラムダ式 – ありそうな例  ラムダ式を使った記法  method(list, p -> p.age >= 20);
  • 24. ラムダ式 – ありそうな例  ラムダ式を使った記法  method(list, p -> p.age >= 20); アロー演算子 (ハイフン+大なり)
  • 25. ラムダ式 – ありそうな例  ラムダ式を使った記法  method(list, p -> p.age >= 20); 引数 返す値
  • 26. ラムダ式 – ありそうな例  ラムダ式 = 匿名クラスの省略記法  匿名クラス  new PersonFilter(){ boolean test(Person p) { return p.age >= 20; } });  ラムダ式  p -> p.age >= 20
  • 27. ラムダ式 – ありそうな例  省略しない書き方  method(list,(Person p) -> { return p.age >= 20;}); 引数 処理
  • 28. ラムダ式 – ありそうな例  省略しない書き方  method(list,(Person p) -> { return p.age >= 20;}); 引数の型が推測可能 な場合は不要
  • 29. ラムダ式 – ありそうな例  省略しない書き方  method(list, (p) -> { return p.age >= 20;}); 引数1個なら カッコは不要
  • 30. ラムダ式 – ありそうな例  省略しない書き方  method(list, p -> { return p.age >= 20;}); 単に値を返すだけなら 式だけを書けばOK
  • 31. ラムダ式 – ありそうな例  省略しない書き方  method(list, p -> p.age >= 20);  ↑同じ!↓  method(list,(Person p) -> { return p.age >= 20;});
  • 32. ラムダ式 – 記法の例  引数0個  () -> 1  引数1個  (x) -> x * 2  x -> x * 2  引数1個の場合のみ引数のカッコを省略できる  引数2個  (a, b) -> a - b
  • 34. ラムダ式 – 他の例  Android とか (イベントドリブンでよく見かけるパター ン)  Buttonがクリックされたときの処理を設定する  匿名クラス  button.addOnClickListener(new OnClickListener(){ void onClick() { doSomething(); } });  ラムダ式  button.addOnClickListener( () -> { doSomething(); });
  • 35. ラムダ式 – 他の例  Android とか (イベントドリブンでよく見かけるパター ン)  Buttonがクリックされたときの処理を設定する  匿名クラス  button.addOnClickListener(new OnClickListener(){ void onClick() { doSomething(); } });  ラムダ式  button.addOnClickListener( () -> { doSomething(); }); ・行数が少ない ・インデントが浅い
  • 37. どんなinterfaceにもラムダ式を渡せるの?  引数の型が「関数型interface」の条件を満たしてい る場合だけ  ≒ メソッド数が1個のinterfaceのこと  例外: デフォルトメソッドはあってもいい etc...  interface Example { // メソッド1個なので関数型interface void hoge (); }
  • 38. @FunctionalInterface アノテーション  interfaceが関数型interfaceであると宣言するアノテー ション  これを付けると「関数型interface」の条件を満たさない ときにコンパイルエラーにしてくれる  付けなくても条件を満たせば関数型interfaceになる  @FunctionalInterface interface InvalidExample { // メソッド2個なので関数型interfaceではない // コンパイルエラー void methodA(); void methodB(); }
  • 40. ラムダ式 – 標準の関数型interface  例ではこのようなinterfaceを自分で定義した  interface PersonFilter { /** * pをフィルタに通過させる場合はtrueを返します。 */ boolean test(Person p); }  よく使うinterfaceが標準で定義されている  interface Predicate<T> { boolean test(T elem); // 実際にはもうちょっと複雑な定義 }
  • 41. ラムダ式 – 標準の関数型interface  標準の関数型interfaceを使う場合  public void main(){ method(list, p -> p.age >= 20); }  void method(List<Person> list, Predicate<Person> filter) { for(Person p : list) { if(filter.test(p)) { doSomething(p); } } }
  • 42. ラムダ式 – 標準の関数型interface  いろいろある  引数なし, 戻り値なし  Runnable  引数なし, 戻り値T  Supplier<T>  引数T, 戻り値なし  Consumer<T>  引数T, 戻り値U  Function<T, U>  引数T, 戻り値boolean  Predicate<T>  ほかに30種類くらいあります
  • 43. メソッド参照  interfaceのメソッドと同じシグネチャを持つメソッ ドがあれば、メソッド自体を引数で渡せる  ラムダ式  button.addOnClickListener(() -> {doSomething();});  メソッド参照  button.addOnClickListener(this::doSomething);  コロン2個の後にメソッド名  ラムダ式よりもコードが短くなる  引数リストが隠れるのでわかりづらくなる場合がある
  • 45. Stream API の導入 – for文からの変換  5文字より長い文字列を大文字に変換して処理を行う  for(String s : list) { if (s.length() > 5) { String upper = s.toUpperCase(); method(upper); } }
  • 46. Stream API の導入 – for文からの変換  5文字より長い文字列を大文字に変換して処理を行う  for(String s : list) { if (s.length() > 5) { String upper = s.toUpperCase(); method(upper); } } 絞り込み (filter)
  • 47. Stream API の導入 – for文からの変換  5文字より長い文字列を大文字に変換して処理を行う  for(String s : list) { if (s.length() > 5) { String upper = s.toUpperCase(); method(upper); } } 変換 (map : 写像)
  • 48. Stream API の導入 – for文からの変換  5文字より長い文字列を大文字に変換して処理を行う  for(String s : list) { if (s.length() > 5) { String upper = s.toUpperCase(); method(upper); } } 順次処理 (for each)
  • 49. Stream API の導入 – for文からの変換  5文字より長い文字列を大文字に変換して処理を行う  for(String s : list) { filter (5文字より長い) map (大文字に変換) forEach (methodで処理) }
  • 50. Stream API の導入  Stream APIによる記法  list.stream() .filter( s -> s.length() > 5) .map( s -> s.toUpperCase()) .forEach( s -> {method(s);} );
  • 51. Stream API の導入  Stream APIによる記法  list.stream() .filter( s -> s.length() > 5) .map( s -> s.toUpperCase()) .forEach( s -> {method(s);} ); メソッドチェイン (4行で1文)
  • 52. Stream API の導入  Stream APIによる記法  list.stream() .filter( s -> s.length() > 5) .map( s -> s.toUpperCase()) .forEach( s -> {method(s);} );  for(String s : list) { if (s.length() > 5) { String upper = s.toUpperCase(); method(upper); } } しっぽが無い
  • 54. Stream API のメソッド - Streamの始め方  ListからStreamを作成する  List list = new ArrayList(Arrays.asList(“a”, “b”, “c”)); list.stream()  配列からStreamを作成する  String[] array = {“a”, “b”, “c”}; Arrays.stream(array)  整数を列挙したStreamを作成する  IntStream.range(0, 10)  for(int i=0; i<10; i++) と同じ  IntStream.rangeClosed(0, 10)  for(int i=0; i<=10; i++) と同じ  テキストファイルなどから  BufferedReader br = /*省略*/; br.lines()  1行ぶんの文字列を1要素としたStreamになる
  • 55. Stream API のメソッド – Streamに対する処理  中間処理と終端処理がある  中間処理  Streamの要素を変化させる  戻り値はStream  メソッドチェインで処理が継続  終端処理  Streamの要素を使って 最終的な結果を得る or 処理を行う  戻り値は void とか 要素の型 とか boolean とか
  • 56. Stream API のメソッド – 中間処理  filter (Predicate<T>)  Streamの要素を絞り込む  map (Function<T, U>)  Streamの要素を変換する  別の型に変えてもok  .map(p -> p.name) とか(Person → String)  skip (long n)  Streamの最初のn個の要素を飛ばす  peek (Consumer<T>)  各要素を処理する。forEachに似ているが、Streamを継続できる点で異 なる  デバッグ用  list.stream().peek( s -> {log.debug(s);}).…  etc.
  • 57. Stream API のメソッド – 終端処理  forEach (Consumer<T>)  各要素を処理する  拡張for文とほぼ同じ使い方  for( String s : list) { }  list.stream().forEach( s -> { });  anyMatch (Predicate<T>) allMatch(Predicate<T>)  条件に一致する要素が存在するか / 全て一致するか を booleanで返す  collect (Collector)  Streamの全要素を格納したコレクションを生成して返す  引数には Collectors.toList() などを渡せる  etc.
  • 59. Stream API – 他の例  Listの中身が全て条件を満たすかどうか  Java 7  boolean valid = true; for(Person p : list) { if( p.age < 18 ){ valid = false; break; } }  Java 8  boolean valid = list.stream() .allMatch( p -> p.age >= 18 );
  • 60. Stream API – 他の例  Listの要素を標準出力に表示  java 7  for(String s : list) { System.out.plintln(s); }  java 8 (ラムダ式)  list.stream().forEach(s -> {System.out.println(s);});  java 8 (メソッド参照)  list.stream().forEach(System.out::println);
  • 61. Stream API – 他の例  Listの要素を絞り込んで新しいListに格納する  Java 7  List<String> newList = new ArrayList<>(); for (String s : list) { if (s.length > 5){ newList.add(s); } }  Java 8  List<String> newList = list.stream() .filter( s -> s.length() > 5 ) .collect(Collectors.toList());
  • 62. Stream API – 他の例  Listの要素を全て変換する  List#replaceAll  (Stream APIではなくListの新メソッド)  Java 7  List<String> newList = new ArrayList<>(); for(String s : list) { newList.add(s.toUpperCase()); }  Java 8  list.replaceAll( s -> s.toUpperCase() );
  • 63. Stream API – 他の例  Mapの要素を順次処理  Map#forEach  (Stream API ではなくMapの新メソッド)  java 7  for(String k : map.keySet()){ Object v = map.get(v); method(k, v); }  java 8  map.forEach( (k, v) -> { method(k, v); } );
  • 65. まとめ  ラムダ式  匿名クラスの省略記法  関数型interfaceを引数にとるメソッドに渡せる  標準の関数型interfaceをうまく利用したい  Stream API  コレクションに新しく用意された便利な操作方法  Stream生成 → 中間処理*n → 終端処理  for文やwhile文はだいたいStream APIに書き換えできる  for文禁止時代の到来