狠狠撸

狠狠撸Share a Scribd company logo
ほんとうに便利だった
業務で使えるJava SE8 新機能
Vol.01 Apr/11/2015
Yuki ?Fukuda
DU, ?Rakuten ?Inc.
http://www.rakuten.co.jp/
2
Speaker ?Profile
Yuki ?Fukuda ?(福田 雄貴)
Financial ?Service ?Department, ?DU(April, ?2011-?)
? Web ?Application ?Engineer
? Team ?Manager
Java歴: 会社にはいってから
Introduction:
Java SE8を初めて使った時の話
4
March, ?2014 ?– Launch!
Java ?8 ?リリース
おめでとうございました
5
ある日の先輩エンジニアとの会話
都合よく降ってくる案件
Senpai Engineer:
今度新規Webアプリ構築の話があるんだけど 興味ある?
Fukuda, ?Yuki:
あります
6
その直後の技術管理マネージャーとの会話
選択肢を用意しない交渉
Fukuda, ?Yuki:
今度 新規のWebアプリ開発案件があるらしいんですけど
Java SE8 と Java EE7 でいいですか?
いいですよね?
Technology ?Manager:
いいよ
7
はじまったプロジェクト
n?工期
n?工数
n?人的リソース
約6ヶ月
67人月
なんとかして
8
ぼくの考えた最強のスケジュール
May June July August September October
要件定義
結合テスト
QA?総合テスト
詳細設計
基本設計
開発?単体テスト
9
May June July August September October
提示されたスケジュール
要件定義?設計
テスト
QA
開発
念のため
テスト
10
スケジュール上の問題点
1 要件を決める気がない
3 開発より先に念のためテストがある
2 要件を决めている最中に结合テストが始まる
11
ほんとうに困った問題点
1 要件を決める気がない
3 開発より先に念のためテストがある
2 要件を决めている最中に结合テストが始まる
n?人的リソース
なんとかして
12
3年目の勘
1) この案件は絶対にヤバイ。
2) スーパーエースを全力で
投入しないと自分が死ぬ。
13
所属組織マネージャーとの会話
スーパーエースを全力で投入しないと自分が死ぬ
Fukuda, ?Yuki:
スーパーエースを10人ください
Group ?Manager:
おまえは何を言っているんだ
Fukuda, ?Yuki:
え?
14
はじまったプロジェクト(再掲)
n?工期
n?工数
n?人的リソース
約6ヶ月
67人月
なんとかして
15
所属組織マネージャーとの会話(続き)
表現が良くなかった
Fukuda, ?Yuki:
普通の人の1.5人分働くヤツを7人ください
Group ?Manager:
お前が2人分働けば6人で足りるよね
Fukuda, ?Yuki:
はい。え?
16
祝?開発チーム結成
7名のエンジニア確保に成功
※ただし7国籍
↑福田
17
公用語
俺達には
英語がある
18
朝のあいさつ
現実の会話
Fukuda, ?Yuki:
早安(中国語)
Engineer:
Bonjour(フランス語)
Engineer:
おはよー(日本語)
Engineer:
moi(フィンランド語)
Engineer:
Good morning!(英語)
19
実際の公用語
Java
20
果たして本当にそうか!?
理想 現実
コーディング規約 Java SE8に関する規約なし
世の中のスタンダード 探しても見つからない
Java SE8を解析できない
※いまはできます
21
スーパーエースたちは思った
「信じられるのは自分だけだ」
22
スーパーエースたちは思った
「信じられるのは自分だけだ」
=宗教戦争のはじまり
23
本日のテーマ
宗教戦争の果てに
僕達が見たもの
Main ?Chapter:
ほんとうに便利だった新機能
(1)Stream ?API
26
Stream ?API ?-? for文禁止令
for文禁止
※ついでにwhile文も禁止
27
Stream ?API ?-? 問
いかにして
エンジニアを
for文から
脱却させるか
28
Stream ?API -? IDEによる自動変換
自動変換はお手軽だけど
生成されるコードは微妙
29
Stream ?API ?-? やっぱり自分で书こう!
30
Stream ?API ?-? シンプルに教育
1 Streamの始め方
3 Streamの終わり方
2 Streamのつなぎ方
31
Stream ?API ?-? Streamの始め方(1)
Collection#stream()
「forの代わりにstreamって書け」
32
Stream ?API ?-? Streamの始め方(2)
Arrays#stream(T[] ?array)
配列から始めるときはこちら
33
Stream ?API ?-? Streamの始め方(3)
Files#lines(Path ?path)
ファイル読み書き系のバッチ処理において極めて有能
34
Stream ?API ?-? Streamのつなぎ方(1)
filter(Predicate<? ?super T> predicate)
主な用途:
Streamを流れるデータのバリデーション
データの絞り込み
35
Stream ?API ?-? Streamのつなぎ方(2)
map(Function<? ?super T, ?? ?extends ?R> mapper)
36
Stream ?API ?-? Streamのつなぎ方(3)
peek(Consumer<? ?super T> action)
特にログを吐くときが便利
業務ロジックを動かすときは使わないこと
※サンプルには書いていますが仕事では使ってません
37
Stream ?API ?-? Streamの終わり方(1)
よくある事例:
CollectionをStreamとして処理したあと、最後にCollectionに戻したい
38
Stream ?API ?-? Streamの終わり方(1)
あまりない事例:
StringのStreamをいろいろいじくった最後に結合したい
39
Stream ?API ?-? Streamの終わり方(2)
よくある事例:
Streamの各要素をファイルに書き出したい
StreamはAutoCloseableを実装しているので
try-?with-?resource文のリソースとして利用可能
40
Stream ?API ?-? Streamの終わり方(3)
よくある事例:
なんらかの処理をしたあと n番目の要素がほしい
41
Stream ?API ?-? いいわけパート
0 0.0005 0.001 0.0015 0.002 0.0025 0.003 0.0035 0.004 0.0045 0.005
while
for
Statement ?/ ?Step ?Count
Java ?SE7
Java ?SE8
-80% (※当社比)
-85% (※当社比)
42
Stream ?API ?-? いいわけパート
よくある事例:
検査例外がうまくさばけなかった
43
Stream ?API ?-? いいわけパート
よくある事例:
実質的final制約に負けた
IDEは結構賢いのでStreamへの変換をサジェストしてきません
44
Stream ?API ?-? いいわけパート
あまりない事例:
救いようがないほど複雑なロジックだった
45
Stream ?API ?-? まとめ
実プロジェクトではこれらの事例が複合的に襲ってきますので
for文禁止は弾力的に運用するのがよさそう
「移植したソースを直す時間
がないから」「Streamよくわか
らないから」といった理由で
for文を許可するのはダメ
※今回のプロジェクトでの判断基準は
ラムダ式の -> の右側に{ } が必要になるかどうか
にしました
(2)Method ?References
47
Method ?References ?-? Lambdaも悪くないけど…
.filter(string ?-?> ?string.length() ?> ?6)
ちょっと鬱陶しい(というか仕事でこんなのかきたくない)
48
Method ?References ?-? Lambdaも悪くないけど…
2行以上に渡るラムダ式みたくない
ネストが深い
49
Method ?References ?-? こっちのほうが馴染みがある
他の外部ライブラリのメソッドとかも使いたい
50
Method ?References ?-? そのまま使おうぜ!
51
Method ?References ?-? 厂迟谤别补尘をシンプルに
52
Method ?References ?-? メリット
? Streamが見た目シンプルになる
? 今まで使っていたコードをそのまま再利用できる
? 単体テストが簡単になる
53
Method ?References ?-? デメリット
どうみてもそこにいるべきではないコードが出現している
54
Method ?References ?-? 教訓
ちゃんと関数型インタフェースを実装したクラスの作り方を教育すること
※そういうものが存在するっていうことを教えてあげること
(3)Date ?and ?Time ?API
56
Date ?and ?Time ?API ?-? java.util.Date禁止令
java.util.Date
禁止
※もちろんCalendarも禁止
57
Date ?and ?Time ?API -? メリット
直感的
58
Date ?and ?Time ?API ?-? エンジニアが苦しんだ理由
なぜかMay
59
Date ?and ?Time ?API ?-? 苦しみからの解放
直感的!!
60
Date ?and ?Time ?API ?-? 加算減算
直感的!!
61
Date ?and ?Time ?API ?-? うるう年判定 (Before)
_人人人人人人人人人人人人人_
> 突然のGregorianCalendar <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
62
Date ?and ?Time ?API ?-? うるう年判定 (After)
直感的!!
63
Date ?and ?Time ?API ?-? 和暦 (Before)
ロケールに ja_JP_JP をセットすると
JapaneseImperialCalendar のインスタンスを生成する!
64
Date ?and ?Time ?API ?-? 和暦 (After)
直感的!!
65
Date ?and ?Time ?API ?-? 実際の運用(1)
ZonedDateTimeインスタンスの取得方法を限定する。
66
Date ?and ?Time ?API ?-? 実際の運用(2)
java.util.Dateとの相互変換メソッドを提供する
外部ライブラリの都合で泣く泣くjava.util.Dateを使わされるケースが
多々有ります
67
Date ?and ?Time ?API ?-? 実際の運用(3)
DateTimeFormatterも共通で使うものを用意しておく
68
Date ?and ?Time ?API ?-? 実は。
コード書く人にとっては
そんなに便利になっていない
のでは。
一理ある
69
Date ?and ?Time ?API ?-? 我々が真に獲得したもの
? 変なことをすると例外を吐いてくれる
? Immutable
? スレッドセーフ
? 見た目わかりやすい
という安心感。
(4)Optional
71
Optional ?-? nullチェック禁止令
nullチェック
禁止
72
コードレビューの日常
Optional ?-? 良識あるエンジニアによるレビュー
Code ?Reviewer:
安易にnullを返したらダメです
ちゃんとチェックしてください
意図してnullを返す場合はちゃんとコメントに書いてください
Young ?Engineer:
はい
73
Optional ?-? レビューの結果
nullを返さないソースコード
nullを返す場合はコメントに書く
74
Optional ?-? 後日
別の人が新しいロジックを書きました。
75
コードレビューの日常
Optional ?-? 良識あるエンジニアによるレビュー(2)
Code ?Reviewer:
そこnullが返ってきても大丈夫ですか
ちゃんとチェックしたほうが良くないですか
Young ?Engineer:
はい
76
Optional ?-? レビューの結果(2)
77
Optional ?-? チェックされていると安心する
とても
安全!!
78
Optional ?-? もうやめよう
人間のやる
仕事じゃない
79
Optional ?-? これからの時代
Optional(nullかもしれない値)
80
Optional ?-? nullの可能性があることを主張したい
(1)返り値の型をOptionalにする
(2)返す値をOptionalで包む
81
コードレビューの日常
Optional ?-? これからのレビュー
Code ?Reviewer:
nullが返る可能性があるのなら
Optionalで包んでください
Young ?Engineer:
はい
82
Optional ?-? nullでないことを保証しなければならない
返す値をOptionalから値を取りだす
Optionalが空のときはデフォルト値を返す
83
コードレビューの日常
Optional ?-? これからのレビュー(2)
Code ?Reviewer:
返り値がOptionalではないのなら
nullが返らないように作ってください
Young ?Engineer:
はい
84
Optional ?-? ダメな例
Optional#of(T ?value)はnullを渡すと NullPointerException が発生します
→このメソッドはあまり出番がないです
isPresent() ?+ ?get() ?= ?やってることがnullチェックと同じ
→単純なisPresent()とget()の組み合わせは避けましょう
※isPresent()はifPresent()の処理で例外処理を入れたい場合など、
用途を限って使うのが良いと思います。
85
Optional ?-? プログラマを処刑すべき例
絶対に許さない
86
Optional ?-? orElse() ?orElseGet()
87
Optional ?-? orElseThrow()
88
Optional ?-? 利用にあたって
中途半端が
一番危険
このルールを適用する範囲を明確にしないと
Optionalをちゃんと返すやつとnull返すやつが混在する
カオスコード集が完成します
(5)Others
90
UncheckedIOException
ご利用は計画的に!!
91
String#split()
“When ?there ?is ?a ?positive-?width ?match ?at ?the ?beginning ?of ?this ?string ?
then ?an ?empty ?leading ?substring ?is ?included ?at ?the ?beginning ?of ?the ?
resulting ?array. ?A ?zero-?width ?match ?at ?the ?beginning ?however ?never ?
produces ?such ?empty ?leading ?substring.”
英語版Java ?SE8ドキュメントより引用
http://docs.oracle.com/javase/8/docs/api/java/lang/String.html
92
Collection ?/ ?List ?/ ?Map
Streamを使う前に一度確認を!
Conclusion:
まとめ
94
まとめ
Java ?SE8を仕事でつかってみました
いくつかの新機能について
思ったことを話しました
? Stream ?API
? Method ?References
? Date ?and ?Time ?API
? Optional
? その他
95
まとめ
? シンプル
? 安全
? 古いコードもう見たくない
Java ?SE8 ?すてき!
96
まとめ
Java ?SE8を導入して幸せになろう!
※ただし、コーディング規約や
ポリシーの類は整理が必要
おわり

More Related Content

ほんとうに便利だった業務で使えるJava SE8新機能(JJUG CCC 2015 Spring)