Java8で追加されたAPI Map編 その2

【前提条件】

[環境]
[参考資料]

Java8 APIドキュメント
http://docs.oracle.com/javase/jp/8/api/

【概要】

前回に続いてMapクラスに追加されたメソッドに調べてみました。

【computeメソッド】

Map#computeメソッドはMap内の値を加工するためのメソッドです。

[サンプルコード]
    public static void sampleCompute() {
        
        final Map<Integer, String> mapValue = new HashMap<>();

        mapValue.put(1, "one");
        mapValue.put(2, "two");
        mapValue.put(3, "three");

        final String value1 = mapValue.compute(2, (key, value) -> key + "-" + value);
        final String value2 = mapValue.compute(4, (key, value) -> key + "-" + value);
        System.out.println("return value1 => " + value1);
        System.out.println("return value2 => " + value2);
        mapValue.entrySet().stream().forEach(System.out::println);
    }

Map#computeメソッドのパラメータはキーと加工用の関数オブジェクトです。
キーはMapのキーの型を指定します。

関数オブジェクトはキーと値をパラメータに受け取り、
値と同じ型のオブジェクトを返却します。

[実行結果]
return value1 => 2-two
return value2 => 4-null
1=one
2=2-two
3=three
4=4-null

パラメータで渡した関数オブジェクトによって加工された値は
パラメータで指定したキーに紐付くエントリの値に反映されます。

加工後の値はMap#computeメソッドの戻り値として返却されます。

Mapオブジェクト内にパラメータで指定したキーがなかった場合、
関数オブジェクトには指定したキー値とNullが渡されます。

【computeIfAbsentメソッド】

Map#comuteIfAbsentメソッドは値が設定されていない場合にのみ
加工するためのメソッドです。

[サンプルコード]
    public static void sampleComuputeIfAbsent() {

        final Map<Integer, String> mapValue = new HashMap<>();

        mapValue.put(1, "one");
        mapValue.put(2, "two");
        mapValue.put(3, "three");

        final String value1 = mapValue.computeIfAbsent(4, key -> key + "-" + String.valueOf(key));
        final String value2 = mapValue.computeIfAbsent(2, key -> key + "-" + String.valueOf(key));
        System.out.println("return value1 => " + value1);
        System.out.println("return value2 => " + value2);
        mapValue.entrySet().stream().forEach(System.out::println);

    }

Map#computeメソッドと同じく、パラメータはキーと関数オブジェクトです。
関数オブジェクトのパラメータはMap#computeメソッドと違いキーのみです。

[実行結果]
return value1 => 4-4
return value2 => two
1=one
2=two
3=three
4=4-4

パラメータで指定したキーがない場合のみ加工した結果が設定されます。

Map#comuteIfAbsentメソッドの戻り値は加工後の値ですが、
指定したキーがない場合はキーに紐付く値が返却されます。

【computeIfPresent】

Map#computeIfPresentメソッドは値が設定されている場合にのみ
加工するためのメソッドです。

[サンプルコード]
    public static void sampleComputeIfPresent() {

        final Map<Integer, String> mapValue = new HashMap<>();

        mapValue.put(1, "one");
        mapValue.put(2, "two");
        mapValue.put(3, "three");

        final String returnValue1 = mapValue.computeIfPresent(1, (key, value) -> key + "-" + value);
        final String returnValue2 = mapValue.computeIfPresent(4, (key, value) -> key + "-" + value);
        System.out.println("return value1 => " + returnValue1);
        System.out.println("return value2 => " + returnValue2);
        mapValue.entrySet().stream().forEach(System.out::println);
    }

パラメータはMap#computeメソッドと同じです。

[実行結果]
return value1 => 1-one
return value2 => null
1=1-one
2=two
3=three

パラメータで指定したキーがある場合のみ加工した結果が設定されます。

Map#computeIfPresentメソッドメソッドの戻り値は加工後の値ですが、
指定したキーがない場合はNullが返却されます。

【merge】

Map#mergeメソッドはもcompute系のメソッド同じく
Map内の値を加工するためのメソッドです。

[サンプルコード]
    public static void sampleMerge() {

        final Map<Integer, String> mapValue = new HashMap<>();

        mapValue.put(1, "one");
        mapValue.put(2, "two");
        mapValue.put(3, "three");

        final String returnValue1 = mapValue.merge(2, "-ni", (v1, v2) -> v1 + v2);
        final String returnValue2 = mapValue.merge(4, "four",(v1, v2) -> v1 + v2);

        System.out.println("return value1 => " + returnValue1);
        System.out.println("return value2 => " + returnValue2);
        mapValue.entrySet().stream().forEach(System.out::println);

    }

Map#mergeメソッドのパラメータはキー、値、関数オブジェクトの3つです。

関数オブジェクトのパラメータは2つです。
Mapオブジェクト内のキーに紐付く値と
Map#mergeメソッドにパラメータとして渡した値です。

[実行結果]
return value1 => two-ni
return value2 => four
1=one
2=two-ni
3=three
4=four

指定したキーがある場合は、
Map#mergeメソッドにパラメータとして渡した
値と関数オブジェクト元に加工されます。

加工された値はMap内の値に反映され、
Map#mergeメソッドの戻り値として返却されます。


指定したキーがない場合は
Map#mergeメソッドにパラメータとして渡した
値が設定されてMapオブジェクトに追加されます。

【まとめ】

今回は下記のメソッドを調べました。

  • compute
  • computeIfAbsent
  • computeIfPresent
  • merge

Map内のオブジェクトを加工するメソッドです。
Nullチェックのコードを書かなくても、
処理してくれるメソッドが増えているなと言うのが個人的な印象です。

ただ、使う機会は少ないんじゃないかなと言うのも感じます。