1. 導入:なぜMapの「一括処理」が重要なのか
JavaでMapを扱う際、キーが存在するか確認して、値を取得し、更新してまた保存する……といった「値の更新処理」を何度も書いていませんか?従来の書き方ではif文が重なり、コードが冗長になりがちです。
今回紹介するcompute系メソッドやforEachなどのAPIを使えば、「キーが存在しない場合の初期値設定」や「条件付き更新」を1行で記述できるようになります。これにより、バグを減らし、可読性の高いスッキリとしたコードが書けるようになります。
2. 基礎知識:Mapの新しい操作メソッドとは
Java 8から導入されたこれらのメソッドは、関数型インターフェースを活用しています。
・computeIfAbsent: キーが存在しない時だけ値を計算してセットする。
・computeIfPresent: キーが存在する時だけ値を更新する。
・merge: 既存の値と新しい値を組み合わせて更新する。
・forEach / replaceAll: マップ内の全要素を効率的にループ処理や一括置換する。
これらを使いこなすことで、従来の「containsKey」や「get」を繰り返すコードから卒業しましょう。
3. 実装とサンプルプログラム
実際の現場でよく使うパターンをまとめました。そのままコピーして実行してみてください。
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map
scores.put(“Alice”, 80);
// 1. computeIfAbsent: キーがない場合のみデフォルト値を設定(初期化に便利)
scores.computeIfAbsent(“Bob”, key -> 0);
// 2. merge: キーが存在すれば値を加算、なければ新規追加(集計処理に最適)
scores.merge(“Alice”, 10, Integer::sum);
scores.merge(“Charlie”, 50, Integer::sum);
// 3. forEach: 全要素をループ処理
System.out.println(“— スコア一覧 —“);
scores.forEach((name, score) -> System.out.println(name + “: ” + score));
// 4. replaceAll: 全要素の値を一括で変換(例:ボーナス加算)
scores.replaceAll((name, score) -> score + 5);
System.out.println(“— ボーナス後 —“);
System.out.println(scores);
}
}
4. 応用・注意点:現場での活用と落とし穴
・nullの扱いには注意
compute系メソッドで計算結果として「null」を返すと、そのキー自体がMapから削除されます。意図せずにキーを消してしまわないよう、戻り値にはnullを返さない設計を心がけてください。
・スレッドセーフなMapでの挙動
ConcurrentHashMapなどを使用する場合、compute系のメソッドは「アトミック(不可分)」に実行されます。つまり、複数のスレッドから同時にアクセスされても値が壊れることがありません。これは従来のif文でチェックしてからputする方法では実現できない強力なメリットです。
・読みやすさのバランス
1行で書けるのは便利ですが、複雑な計算をラムダ式の中に詰め込みすぎると、後からコードを読んだ人が苦労します。処理が複雑になる場合は、無理に1行にまとめず、メソッドとして切り出すことも検討しましょう。
これらのメソッドを使いこなすことで、JavaのMap操作はもっと直感的で安全なものになります。ぜひ次回の開発から取り入れてみてください。

コメント