SlideShare a Scribd company logo
from old Java

to modern Java
∼ レビューで学ぶJava8時代のコーディング作法
Acroquest Technology株式会社

JJUG / 関西Javaエンジニアの会
谷本 心 ( @cero_t )
自己紹介
• 名前 : 谷本 心 (たにもと しん)
• 職業 : Javaエンジニア / トラブルシューター

   トラブルシュート教育も引き受けます!
• Twitter : @cero_t
• その他 : 日本Javaユーザ会(JJUG) 幹事

    関西Javaエンジニアの会 主催
さて、

Java8が出ましたが
今日は

関ジャバ∞

と考えて

差し支えないですか?
バ
from old java to java8 - KanJava Edition
from old java to java8 - KanJava Edition
自己紹介
• 名前 : 谷本 心 (たにもと しん)
• 職業 : Javaエンジニア / トラブルシューター

   トラブルシュート教育も引き受けます!
• Twitter : @cero_t
• その他 : 日本Javaユーザ会(JJUG) 幹事

    関西Javaエンジニアの会 主催
さて、

Java8が出ましたが
「どうせ、使うのはまだ先」

とか思ってませんか?
きっと、ずっと先でしょう。
でも、たとえば今
Java6やJava7の勉強を

きちんとできますか?
出始めこそ、

たくさん情報が出てくる
じゃ、いつやるか?
やらせねーよ
(我が家)
from old Java

to modern Java
∼ レビューで学ぶJava8時代のコーディング作法
Acroquest Technology株式会社

JJUG / 関西Javaエンジニアの会
谷本 心 ( @cero_t )
ソースコードレビュー

してますか?
レビューを

する方が多いですか?

受ける方が多いですか?
もちろん

レビューする方が

多いですね
若いんで(?)

レビューを受ける方が

多いです
レビューなんて文化

ありません
履歴書の送付先 :

tanimoto.shin@gmail.com
では早速、コード。
Map<Dept, Long> groupByDeptAndFilter(List<Emp> list) {
return list.stream()
.collect(Collectors.groupingBy(emp -> emp.dept))
.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue()
.stream()
.filter(emp -> emp.sal > 1000)
.count()));
}
何これ読めない
「よく分からないし

for文とmapで

書き直してくれる?」
Map<Dept, Long> groupByDeptClassic(List<Emp> list) {
Map<Dept, Long> result = new HashMap<>();
for (Emp emp : list) {
if (result.containsKey(emp.dept) == false) {
result.put(emp.dept, 0L);
}
if (emp.sal > 1000) {
Long count = result.get(emp.dept);
count++;
result.put(emp.dept, count);
}
}
return result;
}
「あー、読みやすくて

安心するー」
Welcome to

老 害 世 代
from old Java

to modern Java
∼ 老害にならないためのJava8入門
Acroquest Technology株式会社

JJUG / 関西Javaエンジニアの会
谷本 心 ( @cero_t )
Lesson1
今の時代のファイル操作を

理解せよ!
おさらい:
finallyでcloseするという定石
List<String> readFileSE6(String fileName) {
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = reader.readLine()) != null) {
lines.add("<" + line + ">");
}
reader.close();

} catch (IOException ex) {
throw new RuntimeException(ex);
}
return lines;
}
これあかん
やつや!
List<String> readFileSE6(String fileName) {
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = reader.readLine()) != null) {
lines.add("<" + line + ">");
}
} catch (IOException ex) {
throw new RuntimeException(ex); // 例外処理は割愛
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException ex) {
// この例外は無視する?
}
}
return lines;
}
やっぱfinallyで

closeですよね!
finallyでcloseするのは

古い定石

(∼Java6)
try-with-resourcesで

イマドキのJavaに!

(Java7∼)
List<String> readFileSE7_1(String fileName) {
List<String> lines = new ArrayList<>();
try (FileReader in = new FileReader(fileName);
BufferedReader reader
= new BufferedReader(in)) {
String line;
while ((line = reader.readLine()) != null) {
lines.add("<" + line + ">");
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return lines;
}
これが

try-with-resources!
でも!
変なところがあるんです。
List<String> readFileSE7_1(String fileName) {
List<String> lines = new ArrayList<>();
try (FileReader in = new FileReader(fileName);
BufferedReader reader
= new BufferedReader(in)) {
String line;
while ((line = reader.readLine()) != null) {
lines.add("<" + line + ">");
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return lines;
}
!?
List<String> readFileSE7_2(String fileName) {
List<String> lines = new ArrayList<>();
Path path = Paths.get(fileName);
try (BufferedReader reader
= Files.newBufferedReader(path)) {
String line;
while ((line = reader.readLine()) != null) {
lines.add("<" + line + ">");
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
return lines;
}
新定石①:
try-with-resourcesと

FilesとPathで操作する

(Java7∼)
新定石②:

ファイルを一気に読むなら

Files.readAllLines!

(Java7∼)
List<String> readFileSE7_3(String fileName) {
try {
List<String> lines =
Files.readAllLines(Paths.get(fileName));
for (int i = 0; i < lines.size(); i++) {
lines.set(i, "<" + lines.get(i) + ">");
}
return lines;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
一気に読み込むのは便利だけど、
ヒープメモリもたくさん使っちゃう
し、それぞれの行に対する処理が
必要な場合は、どうしてもループを
回し直さなきゃいけないよね。
Java8時代は?
List<String> readFileSE8_1(String fileName) {
List<String> lines = new ArrayList<>();
try {
Files.lines(Paths.get(fileName))
.forEach(s -> lines.add("<" + s + ">"));
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}


return lines;

}
新定石③?:
Files.linesで処理をする

(Java8∼)
新定石③:
forやwhileを見たら

Stream APIへの

置き換えを考える
List<String> readFileSE8_1(String fileName) {
try {
return Files.lines(Paths.get(fileName))
.map(s -> "<" + s + ">")
.collect(Collectors.toList());
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
外部のオブジェクトを

操作しない方が安心。
ちょっとクイズ
void writeSE8_1(String fileName, List<String> lines) {
Path path = Paths.get(fileName);
try (BufferedWriter writer =
Files.newBufferedWriter(path)) {
lines.forEach(s -> writer.write("<" + s + ">"));
} catch (IOException e) {
throw new UncheckedIOException(ex);
}
}
void writeSE8_1(String fileName, List<String> lines) {
Path path = Paths.get(fileName);
try (BufferedWriter writer =
Files.newBufferedWriter(path)) {
lines.forEach(s -> writer.write("<" + s + ">"));
} catch (IOException e) {
throw new UncheckedIOException(ex);
}
}
1. ちゃんと出力されるんじゃない?
2. 順番がグチャグチャになりそうだな・・・
3. コンパイルエラーが起きるよ、これ
4. 実行時例外が起きるよ、これ
void writeSE8_1(String fileName, List<String> lines) {
Path path = Paths.get(fileName);
try (BufferedWriter writer =
Files.newBufferedWriter(path)) {
lines.forEach(s -> writer.write("<" + s + ">"));
} catch (IOException e) {
throw new UncheckedIOException(ex);
}
}
1. ちゃんと出力されるんじゃない?
2. 順番がグチャグチャになりそうだな・・・
3. コンパイルエラーが起きるよ、これ
4. 実行時例外が起きるよ、これ
void writeSE8_2(String fileName, List<String> lines) {
Path path = Paths.get(fileName);
try (BufferedWriter writer =
Files.newBufferedWriter(path)) {
lines.forEach(s -> {
try {
writer.write(s);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
});
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
なんでもかんでも

Lambdaにすれば

良いってもんでもない
Lesson2

文字列操作は

どう変わる?
String joinSE7(List<String> lines) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < lines.size(); i++) {
if (i > 0) {
builder.append(",");
}
builder.append(lines.get(i));
}
return builder.toString();
}
String joinCommons(List<String> lines) {
return StringUtils.join(lines, ",");
}
String joinGuava(List<String> lines) {
return Joiner.on(",").join(lines);
}
みんな大好き

文字列結合
Commons Langとか

Guavaとか使うよねー
String joinSE8(List<String> lines) {
return String.join(",", lines);
}
ようやく搭載された

String#join
新定石④:
String.joinさん

こんにちは!

(Java8∼)
String joinPrefixSE7(List<String> lines) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < lines.size(); i++) {
if (i > 0) {
builder.append(",");
}
builder.append(“<")
.append(lines.get(i))
.append(">");
}
return builder.toString();
}
じゃ、こういうパター
ンはどうするの?
private String joinPrefixCommons(List<String> lines) {
return "<" + StringUtils.join(lines, ">,<") + ">";
}
private String joinPrefixGuava(List<String> lines) {
return "<" + Joiner.on(">,<").join(lines) + ">";
}
助けてJava8マン!
private String joinPrefixSE8(List<String> lines) {
return lines.stream()
.map(s -> "<" + s +”>")
.collect(Collectors.joining(","));
}
要するに

StreamAPIが正義
新定石⑤:
String.joinさん

さようなら!

(Java8∼)
結局、新定石③:
forやwhileを見たら

Stream APIへの

置き換えを考える
Lesson3
forやwhileとifとか

いろいろ行なう集計的なアレ
Map<Dept, Long> groupByDeptAndFilterClassic(List<Emp> list) {
Map<Dept, Long> result = new HashMap<>();
for (Emp emp : list) {
if (result.containsKey(emp.dept) == false) {
result.put(emp.dept, 0L);
}
if (emp.sal > 1000) {
Long count = result.get(emp.dept) + 1;
result.put(emp.dept, count);
}
}
return result;
}
給料が1000ドルを超える社員
の数を部署ごとに集計する
Java8時代は、

最初、こうなると思う
Map<Dept, Long> groupByDeptAndFilterClassic(List<Emp> list) {
Map<Dept, Long> result = new HashMap<>();
for (Emp emp : list) {
result.putIfAbsent(emp.dept, 0L);
if (emp.sal > 1000) {
Long count = result.get(emp.dept) + 1;
result.put(emp.dept, count);
}
}
return result;
}
新しい便利API
でも、新定石③:
forやwhileを見たら

Stream APIへの

置き換えを考える
Map<Dept, Long> groupByDeptAndFilterLambda(List<Emp> list)
{
return list.stream()
.collect(Collectors.groupingBy(emp -> emp.dept))
.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue()
.stream()
.filter(emp -> emp.sal > 1000)
.count()));
}
どうやって書くの?
どうやって読むの?
select
DEPT_ID, COUNT(EMP_ID)
from
EMP
where
EMP.SAL > 1000
group by
EMP.DEPT_ID
SQLと一緒。

勉強して、書いて、

書いて、書いて、

そして、書く。
input : List<Emp>
output : Map<Dept, Empの数>
    ただしEmpは給与が1000より大きい
1. いったん List<Emp> を Map<Dept, List<Emp>> にグルーピングする。
2. Mapの値であるList<Emp>を1000でフィルタリングする。
3. フィルタリング後のList<Emp>をカウントする。
Map<Dept, Long> groupByDeptAndFilterLambda2(List<Emp> list) {
Map<Dept, List<Emp>> groupByDept = list.stream()
.collect(Collectors.groupingBy(emp -> emp.dept));
Map<Dept, List<? super Emp>> filtered = groupByDept.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue()
.stream()
.filter(emp -> emp.sal > 1000)
.collect(Collectors.toList())));
Map<Dept, Long> counted = filtered.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue()
.stream()
.count()));
return counted;
}
Map<Dept, Long> groupByDeptAndFilterLambda(List<Emp> list)
{
return list.stream()
.collect(Collectors.groupingBy(emp -> emp.dept))
.entrySet()
.stream()
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue()
.stream()
.filter(emp -> emp.sal > 1000)
.count()));
}
正直、ちょっとAPIが

足りない感じなので

自分で追加すると良い

(この辺は熟成待ち?)


http://blog.exoego.net/2013/12/control-collector-to-rule-stream-api.html

Collectorを征す者はStream APIを征す(部分的に) - I am programmer and proud
検索: ラムダ禁止
まとめ
forとwhileを見たら

Lambda化を考えよう
レビューで

forとwhileを見つけたら

Lambda化させよう
レビューで

100行ぐらいの

Lambdaが出てきたら
…
自分たちの標準として

どうすれば読みやすくするか

チームで考えよう!
from old Java

to modern Java
∼ 老害にならないためのJava8入門
Acroquest Technology株式会社

JJUG / 関西Javaエンジニアの会
谷本 心 ( @cero_t )
あ、そうそう
from old Java

to modern Java
がきっかけで
Java本格入門(仮)
鋭意執筆中!
頑張ります
m(_ _)m
Let s Study Java8!

More Related Content

What's hot (9)

PDF
Angular Interview Questions-PDF.pdf
JohnLeo57
 
PDF
테스트자동화 성공전략
SangIn Choung
 
PPTX
Test automation proposal
Mihai-Cristian Fratila
 
PPTX
Angular overview
Thanvilahari
 
PPTX
Introduction to ParSeq: to make asynchronous java easier
Junchuan Wang
 
PPT
Effective Java - Enum and Annotations
Roshan Deniyage
 
PDF
Introduction to thymeleaf
NexThoughts Technologies
 
PDF
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
PPTX
Spring Boot
Jiayun Zhou
 
Angular Interview Questions-PDF.pdf
JohnLeo57
 
테스트자동화 성공전략
SangIn Choung
 
Test automation proposal
Mihai-Cristian Fratila
 
Angular overview
Thanvilahari
 
Introduction to ParSeq: to make asynchronous java easier
Junchuan Wang
 
Effective Java - Enum and Annotations
Roshan Deniyage
 
Introduction to thymeleaf
NexThoughts Technologies
 
Left and Right Folds - Comparison of a mathematical definition and a programm...
Philip Schwarz
 
Spring Boot
Jiayun Zhou
 

Viewers also liked (20)

PDF
徹底解説!Project Lambdaのすべて in Fukuoka #j8fk
bitter_fox
 
PDF
What's new in Java 8
jclingan
 
PPT
whats new in java 8
Dori Waldman
 
PDF
TDC 2015 - Java: from old school to modern art!
Marcos Ferreira
 
PPTX
Java 8 Features
Leninkumar Koppoju
 
PDF
Java 8: the good parts!
Andrzej Grzesik
 
PDF
Java SE 8 lambdaで変わる プログラミングスタイル
なおき きしだ
 
PDF
50 new things you can do with java 8
José Paumard
 
PDF
Spring4-DevLove発表資料
Yuichi Hasegawa
 
PPTX
Memory Management: What You Need to Know When Moving to Java 8
AppDynamics
 
PDF
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
心 谷本
 
PDF
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View!
心 谷本
 
PDF
今すぐ始めるCloud Foundry #hackt #hackt_k
Toshiaki Maki
 
PDF
Java 8, Streams & Collectors, patterns, performances and parallelization
José Paumard
 
PDF
Short Lived Tasks in Cloud Foundry #cfdtokyo
Toshiaki Maki
 
PDF
Spring Framework ふりかえりと4.3新機能
kimulla
 
PDF
Implement Service Broker with Spring Boot #cf_tokyo
Toshiaki Maki
 
PDF
From Zero to Hero with REST and OAuth2 #jjug
Toshiaki Maki
 
PPTX
Spring Framework 4.3から5.0へ
movmov
 
PDF
from old Java to modern Java
心 谷本
 
徹底解説!Project Lambdaのすべて in Fukuoka #j8fk
bitter_fox
 
What's new in Java 8
jclingan
 
whats new in java 8
Dori Waldman
 
TDC 2015 - Java: from old school to modern art!
Marcos Ferreira
 
Java 8 Features
Leninkumar Koppoju
 
Java 8: the good parts!
Andrzej Grzesik
 
Java SE 8 lambdaで変わる プログラミングスタイル
なおき きしだ
 
50 new things you can do with java 8
José Paumard
 
Spring4-DevLove発表資料
Yuichi Hasegawa
 
Memory Management: What You Need to Know When Moving to Java 8
AppDynamics
 
人気番組との戦い! Javaシステムのパフォーマンスチューニング奮闘記
心 谷本
 
Let's reconsider about collecting logs. Plus, visiting elastic@Moutain View!
心 谷本
 
今すぐ始めるCloud Foundry #hackt #hackt_k
Toshiaki Maki
 
Java 8, Streams & Collectors, patterns, performances and parallelization
José Paumard
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Toshiaki Maki
 
Spring Framework ふりかえりと4.3新機能
kimulla
 
Implement Service Broker with Spring Boot #cf_tokyo
Toshiaki Maki
 
From Zero to Hero with REST and OAuth2 #jjug
Toshiaki Maki
 
Spring Framework 4.3から5.0へ
movmov
 
from old Java to modern Java
心 谷本
 
Ad

Similar to from old java to java8 - KanJava Edition (20)

KEY
Java7再入門講座
Takafumi Yoshida
 
PDF
ゆるふわJava8入門
dcubeio
 
PPTX
Project lambda
Appresso Engineering Team
 
PDF
「いいコード」をみんなで書こう!
tq_ed
 
PDF
明日から使える Java SE 7
Yuichi Sakuraba
 
PDF
What is java_se_7
TakumiIINO
 
KEY
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
 
PDF
Javaセキュアコーディングセミナー東京第3回講義
JPCERT Coordination Center
 
PDF
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
PPT
Eclipse を使った java 開発 111126 杉浦
urasandesu
 
ODP
こんにちはGroovy
irof N
 
PDF
函館IKA Eclipse活用術
Masahiro Wakame
 
PDF
DSL by JRuby at JavaOne2012 JVM language BoF #jt12_b101
Takeshi AKIMA
 
PDF
Javaセキュアコーディングセミナー東京第3回演習の解説
JPCERT Coordination Center
 
PDF
Scala2.8への移行
guest5f4320
 
PDF
Scala2.8への移行
Takeda Hiroyuki
 
PDF
夏だからJava再入門
Katsumi Honda
 
PDF
Scala conf2013
Takafumi Ikeda
 
PDF
夜子まま塾講義6(androidでhello world)
Masafumi Terazono
 
PDF
Java8から17へ
onozaty
 
Java7再入門講座
Takafumi Yoshida
 
ゆるふわJava8入門
dcubeio
 
「いいコード」をみんなで書こう!
tq_ed
 
明日から使える Java SE 7
Yuichi Sakuraba
 
What is java_se_7
TakumiIINO
 
関ジャバ JavaOne Tokyo 2012報告会
Koichi Sakata
 
Javaセキュアコーディングセミナー東京第3回講義
JPCERT Coordination Center
 
第三回ありえる社内勉強会 「いわががのLombok」
yoshiaki iwanaga
 
Eclipse を使った java 開発 111126 杉浦
urasandesu
 
こんにちはGroovy
irof N
 
函館IKA Eclipse活用術
Masahiro Wakame
 
DSL by JRuby at JavaOne2012 JVM language BoF #jt12_b101
Takeshi AKIMA
 
Javaセキュアコーディングセミナー東京第3回演習の解説
JPCERT Coordination Center
 
Scala2.8への移行
guest5f4320
 
Scala2.8への移行
Takeda Hiroyuki
 
夏だからJava再入門
Katsumi Honda
 
Scala conf2013
Takafumi Ikeda
 
夜子まま塾講義6(androidでhello world)
Masafumi Terazono
 
Java8から17へ
onozaty
 
Ad

More from 心 谷本 (11)

PDF
JJUG CCC 2015 Fall keynote
心 谷本
 
PDF
Spring Bootをはじめる時にやるべき10のこと
心 谷本
 
PDF
Spring Boot + Netflix Eureka
心 谷本
 
PDF
プレゼンの技術 2 実践編
心 谷本
 
PDF
プレゼンの技術 1 考え方
心 谷本
 
PDF
プレゼンの技術
心 谷本
 
PDF
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡
心 谷本
 
KEY
日本一細かいJavaOne2011報告
心 谷本
 
KEY
勝敗は常に見積もりで決まる〜Redmineを使った時間記録の話
心 谷本
 
PDF
日本で二番目に「細かい」JavaOne2011報告
心 谷本
 
PDF
[関ジャバ]Java News 2011 Mar
心 谷本
 
JJUG CCC 2015 Fall keynote
心 谷本
 
Spring Bootをはじめる時にやるべき10のこと
心 谷本
 
Spring Boot + Netflix Eureka
心 谷本
 
プレゼンの技術 2 実践編
心 谷本
 
プレゼンの技術 1 考え方
心 谷本
 
プレゼンの技術
心 谷本
 
実例Javaトラブルシューティング! 〜稼働中のシステムを立て直した半年間の軌跡
心 谷本
 
日本一細かいJavaOne2011報告
心 谷本
 
勝敗は常に見積もりで決まる〜Redmineを使った時間記録の話
心 谷本
 
日本で二番目に「細かい」JavaOne2011報告
心 谷本
 
[関ジャバ]Java News 2011 Mar
心 谷本
 

from old java to java8 - KanJava Edition