LoginSignup
74

More than 5 years have passed since last update.

Java8でListとかMapに追加されたメソッドをいくつか試してみる

Posted at

API ドキュメントを眺めて目についたメソッドを試してみる。

Map が色々追加されている。

環境

Java

1.8.0

Collection

removeIf(Predicate<? super E> filter)

package java8;

import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<String> list = Arrays.asList("hoge", "fuga", "piyo");

        System.out.println("before : " + list);
        list.removeIf(str -> str.contains("g"));
        System.out.println("after : " + list);
    }
}
実行結果
before : [hoge, fuga, piyo]
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161)
    at java.util.AbstractList$Itr.remove(AbstractList.java:374)
    at java.util.Collection.removeIf(Collection.java:415)
    at java8.Main.main(Main.java:12)
Java Result: 1

( ´゚ω゚)・;'.、ブッ

気を取り直して。。。

package java8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("hoge", "fuga", "piyo"));

        System.out.println("before : " + list);
        list.removeIf(str -> str.contains("g"));
        System.out.println("after : " + list);
    }
}
before : [hoge, fuga, piyo]
after : [piyo]

Collection インターフェースに追加されたデフォルト実装。

各要素に対して filter で指定した関数を実行して、 true を返した要素を削除する。
要素が削除された場合は、 true を返却し、1つも削除されない場合は false を返す。

List

replaceAll(UnaryOperator operator)

package java8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("hoge", "fuga", "piyo"));

        System.out.println("before : " + list);
        list.replaceAll(str -> str.toUpperCase());
        System.out.println("after : " + list);
    }
}
実行結果
before : [hoge, fuga, piyo]
after : [HOGE, FUGA, PIYO]

リストの各要素に対して operator を適用して、 operator が返した値をリストにセットし直す。

sort(Comparator<? super E> c)

package java8;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>(Arrays.asList("hoge", "fuga", "piyo"));

        System.out.println("before : " + list);
        list.sort((s1, s2) -> s1.compareTo(s2));
        System.out.println("after : " + list);
    }
}
実行結果
before : [hoge, fuga, piyo]
after : [fuga, hoge, piyo]

リストを指定した Comparator を使ってソートする。
デフォルトの実装は Collections.sort(List<T> list, Comparator<? super T> c) を使う。

Map

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.compute("hoge", (key, old) -> "<" + old + ">");
        map.compute("fuga", (key, old) -> null);
        map.compute("fizz", (key, old) -> "FIZZ");
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {hoge=<HOGE>, piyo=PIYO, fizz=FIZZ}

第一引数で渡した key でマップを検索し、そのキーと取得した値を第二引数で指定した remappingFunction に渡す。

remappingFunction が null 以外の値を返した場合は、マップの中身をその値で置き換える。
remappingFunction が null を返した場合、そのキーのエントリは削除される。

computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.computeIfAbsent("hoge", (key) -> null /*ここは実行されない*/);
        map.computeIfAbsent("fizz", (key) -> "FIZZ");
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {hoge=HOGE, fuga=FUGA, piyo=PIYO, fizz=FIZZ}

key で指定したキーでマップを検索した結果が null の場合、第二引数で指定した mappingFunction が実行される。

mappingFunction が null 以外の値を返した場合、そのときのキーと値がマップに追加される。

デフォルトの実装は同期されないので、マルチスレッド使うときは注意。
ConcurrentHashMapcomputeIfAbsent() は同期するようにデフォルトメソッドをオーバーライドしており、そのことが API ドキュメントに明記されている。

computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.computeIfPresent("hoge", (key, old) -> "<" + old + ">");
        map.computeIfPresent("fuga", (key, old) -> null);
        map.computeIfPresent("fizz", (key, old) -> "FIZZ" /*ここは実行されない*/);
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {hoge=<HOGE>, piyo=PIYO}

key で指定した値でマップを検索して、 null 以外の値を返した場合は remappingFunction を実行する。

remappingFunction が null 以外の値を返した場合は、マップの中身をその値で置き換える。
remappingFunction が null を返した場合、そのキーのエントリは削除される。

forEach(BiConsumer<? super K,? super V> action)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        map.forEach((key, value) -> System.out.printf("key=%s, value=%s%n", key, value));
    }
}
実行結果
key=hoge, value=HOGE
key=fuga, value=FUGA
key=piyo, value=PIYO

マップのエントリを走査して、 action にキーと値を渡す。

getOrDefault(Object key, V defaultValue)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.printf("map[hoge] = %s%n", map.getOrDefault("hoge", "AAA"));
        System.out.printf("map[fizz] = %s%n", map.getOrDefault("fizz", "default value"));
    }
}
実行結果
map[hoge] = HOGE
map[fizz] = default value

key で指定したエントリがマップに存在しない場合、 defaultValue で指定した値を返す。

マップに存在するかどうかは、 containsKey() を使っている。

merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();

        System.out.println("before : " + map);

        for (int i=0; i<4; i++) {
            StringBuilder sb = new StringBuilder(i + " : ");

            map.merge("hoge", 0, (oldValue, value) -> {
                sb.append("oldValue=").append(oldValue).append(", value=").append(value);
                return oldValue + 1;
            });

            System.out.println(sb);
        }

        System.out.println("after : " + map);
    }
}
実行結果
before : {}
0 : 
1 : oldValue=0, value=0
2 : oldValue=1, value=0
3 : oldValue=2, value=0
after : {hoge=3}

指定したキーがマップに存在しない場合は第二引数の値をセットする。
既にマップに存在する場合は、第三引数で指定した関数を実行して、その戻り値をセットする。

詳細なロジックは以下。

  1. key で指定した値でマップを検索する。
  2. 検索した結果が null の場合は、 value で指定した値を取得する。
  3. 検索した結果が null でない場合は、 remappingFunction を実行し、その戻り値を取得する。
  4. 取得した値(valueremappingFunction の戻り値)が null の場合は、 key に紐づくエントリを削除する。
  5. null でない場合は、取得した値でエントリの値を上書きする。

remove(Object key, value)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.remove("hoge", "HOGE");
        map.remove("fuga", "****");
        map.remove("****", "PIYO");
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {fuga=FUGA, piyo=PIYO}

keyvalue で指定した組み合わせのエントリーがマップに存在する場合に限り、そのエントリを削除する。

replace(K key, oldValue, newValue)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.replace("hoge", "HOGE", "REPLACE");
        map.replace("fuga", "****", "NO REPLACE");
        map.replace("****", "PIYO", "NO REPLACE");
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {hoge=REPLACE, fuga=FUGA, piyo=PIYO}

keyoldValue で指定した組み合わせのエントリーがマップに存在する場合に限り、そのエントリの値を newValue で書き換える。

replace(K key, V value)

package java8;

import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("hoge", "HOGE");
        map.put("fuga", "FUGA");
        map.put("piyo", "PIYO");

        System.out.println("before : " + map);
        map.replace("hoge", "REPLACE");
        map.replace("****", "NO REPLACE");
        System.out.println("after : " + map);
    }
}
実行結果
before : {hoge=HOGE, fuga=FUGA, piyo=PIYO}
after : {hoge=REPLACE, fuga=FUGA, piyo=PIYO}

key で指定したエントリがマップに存在する場合、そのエントリの値を value で指定した値で置き換える。

エントリが存在するかどうかには containsKey() が使用される。

参考

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
74