書き方(Java8以降)
map.merge(key, 1, Integer::sum);
動かしてみる
jshell> Map<String, Integer> map = new HashMap<>();
map ==> {}
jshell> map.put("apple", 0);
$2 ==> null
jshell> map.get("apple");
$3 ==> 0
jshell> map.merge("apple", 1, Integer::sum);
$4 ==> 1
jshell> map.get("apple");
$5 ==> 1
jshell> map.merge("apple", 1, Integer::sum);
$6 ==> 2
jshell> map.get("apple");
$7 ==> 2
なんで?
IntegerのsumメソッドとMapのmergeメソッドを調べましょう
Integer.sum
2つの引数を単純に加算しているだけです。
sum
public static int sum(int a,
int b)
+演算子のように、2つの整数を加算します。
パラメータ:
a - 第1オペランド
b - 第2オペランド
戻り値:
aとbの合計
導入されたバージョン:
1.8
Map.merge
default V merge(K key, V value, BiFunction super V,? super V,? extends V> remappingFunction)
指定されたキーがまだ値と関連付けられていないかnullと関連付けられている場合、指定されたnull以外の値に関連付けます。それ以外の場合は、指定された再マッピング関数の結果で関連する値を置換し、結果がnullの場合は削除します。
つまり、第2引数のvalue
はnullだった場合のデフォルト値で、nullでない場合は第3引数の関数の結果が設定されます。
第3引数の関数も引数を2つとります。
第3引数の関数の1つ目の引数はkeyに対してのvalueです。
第3引数の関数の2つ目の引数は第2引数と同じvalueがnullだった場合の値です。
変数に名前をつけるとこんな感じでしょうか
map.merge(key, defaultValue, (value, defaultValue) -> function());
つまり?
map.merge(key, 1, Integer::sum)
はデフォルト値をstep(1回の処理で加算される数)のように扱い、valueとデフォルト値をIntegerのsumをメソッド参照で合算しています。
参考
あと、『Effective Java 第3版』を読んでたら、項目43ラムダよりもメソッド参照を選ぶ(P199)にもこの書き方は言及されてました。