Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

null使ったら負け福岡版

7.510 Aufrufe

Veröffentlicht am

  • Als Erste(r) kommentieren

null使ったら負け福岡版

  1. 1. Optionalとは ● java.util.Optional<T> ● ScalaでいうOption ● HaskellでいうMaybe ● 値をもつかもたないか
  2. 2. Optionalを用意する ● 値がある Optional.of(str) – nullを渡すとぬるぽ ● 値がない Optional.empty() ● 値があるかどうかわからない Optional.ofNullable(str)
  3. 3. 値の取得 ● get() – 値がないときNoSuchElementException ● orElse(defaultValue) – 値がないときdefaultValue ● orElseGet(() -> defaultValue) – 値がないときにdefaultValue取得処理 ● orElseThrow(() -> new Exception()) – 値がないとき例外を生成して投げる
  4. 4. 値があるかどうか判定する if(ostr.isPresent()){ System.out.println(ostr.get()); } ● isPresent ● Java8的ではない
  5. 5. 値があるときだけ操作する ● ifPresent Optional<String> ostr = Optional.of(str); ostr.ifPresent(s -> { System.out.println(s.length()); });
  6. 6. 別の値に変換する ● map ● flatMap Optional<String> ostr = Optional.of(str); ostr.map(String::length) .ifPresent(System.out::println);
  7. 7. 条件に従うものだけ値を使う ● filter Map<String, String> myMap; Optional<String> ostr = Optional.of(str); ostr.filter(s -> s.length() < 5) .map(s -> myMap.get(s)) .ifPresent(System.out::println);
  8. 8. 例 ● マシンの管理者の住所が福岡のときにマンション 名の最初5文字を表示。ただし管理者や住所やマ ンション名はnullのときがある。そのときは空文字
  9. 9. Optional ● マシンの管理者の住所が福岡のときにマンション 名の最初5文字を表示。ただし管理者や住所やマ ンション名はnullのときがある。そのときは空文字 System.out.println(Optional.of(machine) .map(m -> m.getAdmin()) .filter(adm -> Optional.ofNullable(adm.getAddr()) .map(adr -> adr.getPref() == 40) .orElse(false)) .map(adm -> adm.getAddr()) .map(adr -> adr.getMansion()) .map(man -> man.substring(0, 5) .orElse(“”));
  10. 10. ちょっと使えるイディオム ● foo.execBar()がnullじゃなければその値、nullな ら違う値 ※execBar() はちょっと重い処理 Optional.ofNullable(foo.execBar()).orElse(defValue) String s = foo.execBar(); if(s == null){ s = defValue; }
  11. 11. モナド! ● nullのある世界とない世界の分離 ● マサカリが飛び交う世界との出会い – オブジェクト指向->ソフトウェア工学 ● 鈍器が飛んでくる – 関数型->コンピュータ科学 ● するどいマサカリ
  12. 12. nullを使っていいところ悪いところ ● ローカル変数 ○ – Optionalを使うと安心感はある ● 引数 △ – メソッド利用者に不便がある – ほとんどの場合はメソッドオーバーロードで対応できる ● 戻り値 × – nullを外にもらさない ● フィールド × – nullを外にもらさない、もちこまない
  13. 13. Java8のほかの作法 ● Streamでの注意 ● メソッド参照とラムダの使い分け ● 遅延実行をいかす ● Mapを活用する ● 制御構造を自作する
  14. 14. Streamでの注意 ● 副作用に気をつける ● 例外とは相性がわるい
  15. 15. 副作用に気をつける ● 副作用を使う基準 – 中間操作 × – 終端操作 ● reduce △ ● forEach ○
  16. 16. 例外との相性 ● ラムダは関数の世界 ● Streamも関数の世界 ● 例外はgoto。手続きの世界 ● Javaの例外は思想が古い ● 根本的に相性悪い ● 泣く泣くいろいろ対策 – ex:ラッピングメソッドを定義する。
  17. 17. 遅延実行をいかす ● 値が使われる可能性の低い引数の構築に時間がか かるとき ● Logger ● Optional – Optional#orElseGet – Optional#orElseThrow logger.debug(bigObject.toString()); logger.fine(() -> bigObject.toString());
  18. 18. Mapを活用する ● 便利なメソッドが追加されている – getOrDefault ● Map<?, LIst<?>>が使いやすくなった ● メモ化
  19. 19. Map<?, List<?>> ● 追加 – Map#computeIfAbsent ● 削除 – Map#computeIfPresent modifiedTuples.computeIfPresent(mt.oldtuple.rid, (rid, list) -> { list.remove(mt); return list.isEmpty() ? null : list; }); modifiedTuples.computeIfAbsent(mt.oldtuple.rid, rid -> new LinkedList()).push(mt);
  20. 20. メモ化 ● Map#computeIfAbsent – 値があればその値、なければ計算を行って結果を Mapに格納しつつ返す。
  21. 21. 制御構造を自作する ● カスタムwith ● カスタム分岐 ● カスタムループ
  22. 22. カスタムwith ● try-with-resource public static void withTran(Transaction tx, Runnable proc){ try{ proc.run(); tx.commit(); }catch(Exception ex){ tx.rollback(); } } withTran(tx, () -> { // Databaseアクセス! });
  23. 23. カスタム分岐 ● パターンマッチ – 型安全なオブジェクトごとの操作と分解 http://d.hatena.ne.jp/nowokay/20131212#1386820115
  24. 24. カスタムループ ● forEach ● zip
  25. 25. zip ● ふたつのStreamをまとめる ● indexを振ったりしたい
  26. 26. Pairとzip http://d.hatena.ne.jp/nowokay/20140321#1395371615 public static void main(String[] args) { List<String> prefs = Arrays.asList("ほっかいどう", "ちば", "とうきょう", "しが", "やまぐち", "さが", "みやざき"); StreamUtils.zip( IntStream.iterate(1, SUCC).boxed(), prefs.stream().filter(s -> s.length() <= 2)) .forEach(p -> System.out.printf( "%d:%s%n", p.left, p.right)); }
  27. 27. メソッド参照とラムダの使い分け ● メソッド参照は引数を隠す – events.stream().flatMap(Event::getMember) .map(Member::getTelephone) .forEach(tels::add) ● 読み解くのにコンテキスト理解が必要 – メソッドに渡すためのメソッド ○ – 引数ひとつのメソッド △ – 引数複数のメソッド ×
  28. 28. Java8の弱点 ● 型推論が案外弱い http://d.hatena.ne.jp/nowokay/20140107#1389093206
  29. 29. DateTime APIについて ● DateTime APIべんり! ● DateTime APIややこしい! ● DateTime APIめんどくさい!
  30. 30. DateTimeAPIは ● ISO8601の実装 ● ISO8601がややこしい! ● ISO8601がめんどくさい!
  31. 31. ISO8601は ● 現実の時間の定義 ● 現実の時間がややこしい! ● 現実の時間がめんどくさい!
  32. 32. 現実の時間は ● アウグストゥス – 神が世界を作る前に時間はあったのか ● デカルト・ニュートン – 絶対時間・絶対空間 ● カント – 時間はア・プリオリ ● マクタガート – 時間は実在しない! ● 相対論 – 時間と空間は一緒 ● ハイデガー – 時間こそ人間の存在論的意味だ!
  33. 33. つまり ● 時間はめんどい ● だからISO8601もめんどい ● だからDate Time APIもめんどい
  34. 34. まとめ ● いろいろ便利 ● いろいろめんどい ● 折り合いつけつつ使いましょう

×