computeとmergeによるアトミックなMap更新
複数ステップのMap検索と変更をcomputeIfAbsent()、compute()、merge()に置き換える。
コード比較
✕ Manual lookup and update
List<String> values = groups.get(key);
if (values == null) {
values = new ArrayList<>();
groups.put(key, values);
}
values.add(value);
✓ Java 8+
groups.computeIfAbsent(key, ignored -> new ArrayList<>())
.add(value);
このコードに問題がありますか? お知らせください。
モダンな方法が優れている理由
検索回数の削減
同じキーへの繰り返しアクセスを回避できます。
優れた並行処理セマンティクス
並行Mapでは、サポートされる更新をアトミックに実行できます。
明確な意図
初期化ルールがアクセス処理のそばに記述されます。
旧来のアプローチ
get() + nullチェック + put()
モダンなアプローチ
computeIfAbsent()
JDKバージョン
8
難易度
中級
JDKサポート
computeとmergeによるアトミックなMap更新
利用可能
JDK 8(2014年3月)以降、広く利用可能
仕組み
Mapの計算メソッドは、検索と更新の意図を1つの操作にまとめます。遅延初期化にはcomputeIfAbsent()、既存の値に基づいて新しい値を決める場合はcompute()、指定した値をMap内の既存値と結合する場合はmerge()を使用します。並行Map実装では、サポートされる計算操作により、get()とput()を個別に呼び出すことで生じる競合も回避できます。
関連ドキュメント
証明