Your SlideShare is downloading. ×
from old java to java8 - KanJava Edition
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

from old java to java8 - KanJava Edition

85
views

Published on

from old Java to modern Java : reloaded …

from old Java to modern Java : reloaded
for Kansai Java Engineers' Group

Published in: Software

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
85
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. from old Java
 to modern Java ∼ レビューで学ぶJava8時代のコーディング作法 Acroquest Technology株式会社
 JJUG / 関西Javaエンジニアの会 谷本 心 ( @cero_t )
  • 2. 自己紹介 • 名前 : 谷本 心 (たにもと しん) • 職業 : Javaエンジニア / トラブルシューター
    トラブルシュート教育も引き受けます! • Twitter : @cero_t • その他 : 日本Javaユーザ会(JJUG) 幹事
     関西Javaエンジニアの会 主催
  • 3. さて、
 Java8が出ましたが
  • 4. 今日は
 関ジャバ∞
 と考えて
 差し支えないですか?
  • 5.
  • 6. 自己紹介 • 名前 : 谷本 心 (たにもと しん) • 職業 : Javaエンジニア / トラブルシューター
    トラブルシュート教育も引き受けます! • Twitter : @cero_t • その他 : 日本Javaユーザ会(JJUG) 幹事
     関西Javaエンジニアの会 主催
  • 7. さて、
 Java8が出ましたが
  • 8. 「どうせ、使うのはまだ先」
 とか思ってませんか?
  • 9. きっと、ずっと先でしょう。
  • 10. でも、たとえば今
  • 11. Java6やJava7の勉強を
 きちんとできますか?
  • 12. 出始めこそ、
 たくさん情報が出てくる
  • 13. じゃ、いつやるか?
  • 14. やらせねーよ (我が家)
  • 15. from old Java
 to modern Java ∼ レビューで学ぶJava8時代のコーディング作法 Acroquest Technology株式会社
 JJUG / 関西Javaエンジニアの会 谷本 心 ( @cero_t )
  • 16. ソースコードレビュー
 してますか?
  • 17. レビューを
 する方が多いですか?
 受ける方が多いですか?
  • 18. もちろん
 レビューする方が
 多いですね
  • 19. 若いんで(?)
 レビューを受ける方が
 多いです
  • 20. レビューなんて文化
 ありません
  • 21. 履歴書の送付先 :
 tanimoto.shin@gmail.com
  • 22. では早速、コード。
  • 23. 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())); }
  • 24. 何これ読めない
  • 25. 「よく分からないし
 for文とmapで
 書き直してくれる?」
  • 26. 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; }
  • 27. 「あー、読みやすくて
 安心するー」
  • 28. Welcome to
 老 害 世 代
  • 29. from old Java
 to modern Java ∼ 老害にならないためのJava8入門 Acroquest Technology株式会社
 JJUG / 関西Javaエンジニアの会 谷本 心 ( @cero_t )
  • 30. Lesson1 今の時代のファイル操作を
 理解せよ!
  • 31. おさらい: finallyでcloseするという定石
  • 32. 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; } これあかん やつや!
  • 33. 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ですよね!
  • 34. finallyでcloseするのは
 古い定石
 (∼Java6)
  • 35. try-with-resourcesで
 イマドキのJavaに!
 (Java7∼)
  • 36. 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!
  • 37. でも! 変なところがあるんです。
  • 38. 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; } !?
  • 39. 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; }
  • 40. 新定石①: try-with-resourcesと
 FilesとPathで操作する
 (Java7∼)
  • 41. 新定石②:
 ファイルを一気に読むなら
 Files.readAllLines!
 (Java7∼)
  • 42. 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); } } 一気に読み込むのは便利だけど、 ヒープメモリもたくさん使っちゃう し、それぞれの行に対する処理が 必要な場合は、どうしてもループを 回し直さなきゃいけないよね。
  • 43. Java8時代は?
  • 44. 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;
 }
  • 45. 新定石③?: Files.linesで処理をする
 (Java8∼)
  • 46. 新定石③: forやwhileを見たら
 Stream APIへの
 置き換えを考える
  • 47. 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); } } 外部のオブジェクトを
 操作しない方が安心。
  • 48. ちょっとクイズ
  • 49. 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); } }
  • 50. 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. 実行時例外が起きるよ、これ
  • 51. 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. 実行時例外が起きるよ、これ
  • 52. 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); } }
  • 53. なんでもかんでも
 Lambdaにすれば
 良いってもんでもない
  • 54. Lesson2
 文字列操作は
 どう変わる?
  • 55. 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とか使うよねー
  • 56. String joinSE8(List<String> lines) { return String.join(",", lines); } ようやく搭載された
 String#join
  • 57. 新定石④: String.joinさん
 こんにちは!
 (Java8∼)
  • 58. 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(); } じゃ、こういうパター ンはどうするの?
  • 59. private String joinPrefixCommons(List<String> lines) { return "<" + StringUtils.join(lines, ">,<") + ">"; } private String joinPrefixGuava(List<String> lines) { return "<" + Joiner.on(">,<").join(lines) + ">"; }
  • 60. 助けてJava8マン!
  • 61. private String joinPrefixSE8(List<String> lines) { return lines.stream() .map(s -> "<" + s +”>") .collect(Collectors.joining(",")); } 要するに
 StreamAPIが正義
  • 62. 新定石⑤: String.joinさん
 さようなら!
 (Java8∼)
  • 63. 結局、新定石③: forやwhileを見たら
 Stream APIへの
 置き換えを考える
  • 64. Lesson3 forやwhileとifとか
 いろいろ行なう集計的なアレ
  • 65. 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ドルを超える社員 の数を部署ごとに集計する
  • 66. Java8時代は、
 最初、こうなると思う
  • 67. 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
  • 68. でも、新定石③: forやwhileを見たら
 Stream APIへの
 置き換えを考える
  • 69. 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())); }
  • 70. どうやって書くの? どうやって読むの?
  • 71. select DEPT_ID, COUNT(EMP_ID) from EMP where EMP.SAL > 1000 group by EMP.DEPT_ID
  • 72. SQLと一緒。
 勉強して、書いて、
 書いて、書いて、
 そして、書く。
  • 73. input : List<Emp> output : Map<Dept, Empの数>     ただしEmpは給与が1000より大きい 1. いったん List<Emp> を Map<Dept, List<Emp>> にグルーピングする。 2. Mapの値であるList<Emp>を1000でフィルタリングする。 3. フィルタリング後のList<Emp>をカウントする。
  • 74. 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; }
  • 75. 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())); }
  • 76. 正直、ちょっとAPIが
 足りない感じなので
 自分で追加すると良い
 (この辺は熟成待ち?) 
 http://blog.exoego.net/2013/12/control-collector-to-rule-stream-api.html
 Collectorを征す者はStream APIを征す(部分的に) - I am programmer and proud
  • 77. 検索: ラムダ禁止
  • 78. まとめ
  • 79. forとwhileを見たら
 Lambda化を考えよう
  • 80. レビューで
 forとwhileを見つけたら
 Lambda化させよう
  • 81. レビューで
 100行ぐらいの
 Lambdaが出てきたら
  • 82.
  • 83. 自分たちの標準として
 どうすれば読みやすくするか
 チームで考えよう!
  • 84. from old Java
 to modern Java ∼ 老害にならないためのJava8入門 Acroquest Technology株式会社
 JJUG / 関西Javaエンジニアの会 谷本 心 ( @cero_t )
  • 85. あ、そうそう
  • 86. from old Java
 to modern Java がきっかけで
  • 87. Java本格入門(仮) 鋭意執筆中!
  • 88. 頑張ります m(_ _)m
  • 89. Let s Study Java8!

×