Map(Java8)

今更だけど復習の意味で。 意外と把握していないメソッドがいろいろ追加されていたので。

   //データ準備
    Map<Integer, String> map = new HashMap<>();
    map.put(1, "one");
    map.put(2, "two");
    map.put(3, "three");

getOrDefault

従来の取得メソッド(get)に存在しない場合のデフォルト値を設定できるようになったメソッド

   //1 はキーに存在するため、そのまま[one]を返却する
    System.out.println(map.getOrDefault(1, "none"));
    //4 はキーに存在しないため、デフォルト値の[none]を返却する
    System.out.println(map.getOrDefault(4, "none"));

forEach

すべてのエントリに対する処理を記述できるメソッド
引数にBiConsumerをとるので、ラムダ式による記述が可能

   map.forEach((k,v) -> System.out.println(k + v));

replaceAll

各種エントリに対して、指定されたマッピング処理を施して値を置換する

   //#replaceAll 置換する
    //ちなみにこの例だとキーと値を文字列結合しているので、
    //マップ要素は[1=1one, 2=2two, 3=3three] になる。
    map.replaceAll((k, v) -> k + v);
    System.out.println(map);

    //replaceAllは、javaDocにあるように以下と同等
    BiFunction<Integer, String, String> function = (key, value) -> key + value;
    for (Map.Entry<Integer, String> entry : map.entrySet()) {
        entry.setValue(function.apply(entry.getKey(), entry.getValue()));
    }

putIfAbsent

キーが存在しない場合に、指定された値をマップに追加する。
キーが存在していれば値が返却され、キーが存在していない場合はNULLが返る。

   //1 はすでにキーに存在するため、なにも起きない(戻り値は[one])
    System.out.println(map.putIfAbsent(1, "one"));
    //5 は存在しないため、mapに格納され、戻り値はNULL
    System.out.println(map.putIfAbsent(5, "five"));

remove(key, value)

指定したキー及び値に紐づくエントリが存在している場合に削除する。

   System.out.println(map.remove(1, "one"));

replace

値を置換する。オーバーロードされており、無条件で置換するものと、旧値に合致したものを新値に置換するものとにわかれる

    //#replace(key, oldValue, newValue)
    //指定したキー及び値(oldValue)に合致したエントリがある場合にnewValueで置き換える
    //キー及び値が合致するため、キー1の値が「oneone」に置換される(trueが返却される)
    System.out.println(map.replace(1, "one", "oneone"));
    //キーは存在するが値が異なるため、置換はされない(falseが返却される)
    System.out.println(map.replace(2, "second", "twotwo"));

    //キーにが存在する場合に値を置換する
    System.out.println(map.replace(1, "2222"));

computeIfAbsent

指定されたキーがマップに存在していない場合にマッピング関数を使用して値の計算をしてマップへ格納する

    System.out.println(map.computeIfAbsent(6, k -> String.valueOf(k)));

computeIfPresent

指定されたキーの値が存在している場合にキーと値からマッピングの計算を行う

//キー1は存在しているため、計算処理が行われる。この例だとキーと値を文字列結合している。
//戻り値は計算後の値(1one)となる
String result = map.computeIfPresent(1, (key, value) -> key + value);
//キー5は存在しないため、戻り値はNULL。mapの要素に変化なし。
String result2 = map.computeIfPresent(5, (key, value) -> key + value);
System.out.println(result);
System.out.println(result2);

merge

指定されたキーが存在しない場合には指定された値に関連付ける。
そうでない場合は(キーが存在しているとき)、再マッピング関数の結果で値を置換する。

//キー1 は既に存在しているため再マッピング関数が適用され値が置換される
map.merge(1, "one", String::concat);
//キー2 も既に存在している。再マッピング処理が適用される。
//ただし、マッピング処理による結果がNULLのため、Mapからは削除される。
map.merge(2, "two", (k, v) -> null);
//キー3も存在しているため再マッピング関数の適用。キー3に紐づく値は「three333」となる
map.merge(3, "333", (k, v) -> k + v);
//キー4は存在していないキーのため、再マッピング処理は行われずに、指定した値(この例だと「four」)がキーに紐づけられてマップへ追加。
map.merge(4, "four", (k, v) -> v + v);

//一応結果
{1=oneone, 3=three333, 4=four}

今更だけど復習完了。 こうしてみてみると、やっぱりメソッドの命名って大事なんだなってことに気づく。 「値が存在しない場合にputする」とか、処理そのままの命名になっていたりするからなー。 このあたりもしっかり学ばなければいかんわ。