LoginSignup
7
0

More than 3 years have passed since last update.

JavaでMapのバリューを1行でインクリメントする方法

Last updated at Posted at 2020-07-03

書き方(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

Oracleのドキュメント

Map.merge

default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
指定されたキーがまだ値と関連付けられていないかnullと関連付けられている場合、指定されたnull以外の値に関連付けます。それ以外の場合は、指定された再マッピング関数の結果で関連する値を置換し、結果がnullの場合は削除します。

Oracleのドキュメント

つまり、第2引数のvalueはnullだった場合のデフォルト値で、nullでない場合は第3引数の関数の結果が設定されます。

第3引数の関数も引数を2つとります。
第3引数の関数の1つ目の引数はkeyに対してのvalueです。
第3引数の関数の2つ目の引数は第2引数と同じvalueがnullだった場合の値です。

[Java] Map#mergeが分かりづらい。

変数に名前をつけるとこんな感じでしょうか

map.merge(key, defaultValue, (value, defaultValue) -> function());

つまり?

map.merge(key, 1, Integer::sum)はデフォルト値をstep(1回の処理で加算される数)のように扱い、valueとデフォルト値をIntegerのsumをメソッド参照で合算しています。

参考

あと、『Effective Java 第3版』を読んでたら、項目43ラムダよりもメソッド参照を選ぶ(P199)にもこの書き方は言及されてました。

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0