$30 off During Our Annual Pro Sale. View Details »

モダンなJavaの書き方

 モダンなJavaの書き方

2021.02.25
TECH Street
Javaエンジニア勉強会資料

Yuichi.Sakuraba

March 01, 2021
Tweet

More Decks by Yuichi.Sakuraba

Other Decks in Technology

Transcript

  1. モダンなJavaの書き方
    Java in the Box 櫻庭 祐一

    View Slide

  2. Agenda
    Javaが変革する背景
    Javaのトレンド
    では、どう書く?

    View Slide

  3. 自己紹介
    ● Java歴 26年
    ○ Java 1.0αから
    ○ 2005年 Java Champion
    ○ 2007年 JJUG創設メンバー
    ● Client Side Java
    ○ Java SE, JavaFX
    ● 各種著作
    ○ Web+DB Press 連載 “見なおそう! モダンJavaの流儀”
    ○ 書籍 Java SE 7/8 速攻入門

    View Slide

  4. Hardware
    Javaが変革する背景
    Service/Application

    View Slide

  5. Hardware
    マルチコア
    Vector Computing/GPGPU
    大量メモリ
    超高速通信
    Javaが変革する背景
    Service/Application

    View Slide

  6. Hardware
    マルチコア
    Vector Computing/GPGPU
    大量メモリ
    超高速通信
    Javaが変革する背景
    Service/Application
    巨大かつ複雑なシステム
    頻繁な更新

    View Slide

  7. Hardware
    マルチコア
    Vector Computing/GPGPU
    大量メモリ
    超高速通信
    Javaが変革する背景
    Service/Application
    巨大かつ複雑なシステム
    頻繁な更新
    マイクロサービス
    コンテナ
    AI/ML

    View Slide

  8. Javaのトレンド
    可読性の重視
    関数の活用
    Immutable

    View Slide

  9. Javaのトレンド
    可読性の重視
    関数の活用
    Immutable
    var
    switch式
    ラムダ式 ...
    Javaの機能

    View Slide

  10. Javaのトレンド
    可読性の重視
    関数の活用
    Immutable
    var
    switch式
    ラムダ式 ...
    ラムダ式
    Stream API
    Flow (Reactive Stream)
    Javaの機能

    View Slide

  11. Javaのトレンド
    可読性の重視
    関数の活用
    Immutable
    var
    switch式
    ラムダ式 ...
    ラムダ式
    Stream API
    Flow (Reactive Stream)
    Record
    Immutable Collection Factory
    Javaの機能

    View Slide

  12. Javaのトレンド
    可読性の重視
    関数の活用
    Immutable
    var
    switch式
    ラムダ式 ...
    ラムダ式
    Stream API
    Flow (Reactive Stream)
    Record
    Immutable Collection Factory
    Javaの機能
    Java 8
    Java 11LTS
    Java 17LTS

    View Slide

  13. では、どう書く?
    ● ラムダ式を自在に使えるようにする
    ● オブジェクトの状態変化をなるべく避ける
    ○ できればImmutableにする

    View Slide

  14. では、どう書く?
    ● ラムダ式を自在に使えるようにする
    ● オブジェクトの状態変化をなるべく避ける
    ○ できればImmutableにする
    可読性を向上させる
    Multithread Ready
    処理の切り分けを容易にする
    こう書くことで

    View Slide

  15. とりあえず、やってみよう
    顧客クラス
    顧客リストから製品IDごとの購買数のマップに変換する
    public class Customer {

    // 購買履歴を製品IDのリストとして返す
    public List getHistory() { … }
    }

    View Slide

  16. public Map convert(List customers) {
    Map productCountMap = new HashMap<>();
    for (int i = 0; i < customers.size(); i++) {
    Customer customer = customers.get(i);
    List ids = customer.getHistory();
    for (int j = 0; j < ids.size(); j++) {
    int pId = ids.get(j);
    Long productCount = productCountMap.get(pId);
    if (productCount == null) {
    productCountMap.put(pId, 1L);
    } else {
    productCount++;
    productCountMap.put(pId, productCount);
    }
    }
    }
    return productCountMap;
    }
    いにしえの書き方

    View Slide

  17. public Map convert(List customers) {
    Map productCountMap = new HashMap<>();
    for (int i = 0; i < customers.size(); i++) {
    Customer customer = customers.get(i);
    List ids = customer.getHistory();
    for (int j = 0; j < ids.size(); j++) {
    int pId = ids.get(j);
    Long productCount = productCountMap.get(pId);
    if (productCount == null) {
    productCountMap.put(pId, 1L);
    } else {
    productCount++;
    productCountMap.put(pId, productCount);
    }
    }
    }
    return productCountMap;
    }
    いにしえの書き方
    ミュータブルなマップ
    ループ制御とロジックが混在
    分かりにくいループカウンター
    NullPointerExceptionが発生するため
    オートボクシングができない

    View Slide

  18. public Map convert(List customers) {
    Map productCountMap = new HashMap<>();
    for (Customer customer: customers) {
    List ids = customer.getHistory();
    for (int pId: ids) {
    Long productCount = productCountMap.get(pId);
    if (productCount == null) {
    productCountMap.put(pId, 1L);
    } else {
    productCount++;
    productCountMap.put(pId, productCount);
    }
    }
    }
    return productCountMap;
    }
    Java 5だったら
    for-each文に変更

    View Slide

  19. public Map convert(List customers) {
    Map productCountMap
    = customers.stream()
    .flatMap(customer -> customer.getHistory().stream())
    .collect(Collectors.groupingBy(pId -> pId, Collectors.counting()));
    return productCountMap;
    }
    Java 8以降
    マップの要素を変更しないので
    Immutableにすることも可能
    2重ループの展開
    トリッキーなif文の排除

    View Slide

  20. Conclusion
    ● 可読性向上
    ● 関数の活用
    ● 状態変化を避けること
    ● 新しい言語仕様/機能を積極的に試す
    を意識してコードを記述

    View Slide