JavaSE8 Goldへの道(Upgrade to Java SE 8 Programmer 1Z0-810 試験対策)12回目です。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。
インタフェースのdefaultメソッドがどういうものかついてはその3で触れていますが、今回は実際に追加されたものをご紹介していきます。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。
インタフェースのdefaultメソッドがどういうものかついてはその3で触れていますが、今回は実際に追加されたものをご紹介していきます。
Mapに追加されたメソッド
getOrDefault
default V getOrDefault(Object key, V defaultValue) Map<String, String> map = new HashMap<>(); map.getOrDefault("key", "default");
キーにマッピングが存在しない場合、第2引数の値を返します。
「もし戻り値がnullだったら・・・」みたいなことをやらずに済みます。
本当は前回の
「もし戻り値がnullだったら・・・」みたいなことをやらずに済みます。
本当は前回の
Optional
が使えればよかったでしょうが、そうすると型が変わってコンパイルし直しになってしまうので仕方ないですね。putIfAbsent
default V putIfAbsent(K key, V value) Map<String, String> map = new HashMap<>(); map.putIfAbsent("key", "value");
通常の
Map#put
と引数が同じですが、キーにマッピングがないときだけ追加します。Map#containsKey
と二段階の操作が1回で済みます。compute
default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) Map<String, String> map = new HashMap<>(); String msg = "default"; map.compute("key", (k, v) -> v == null ? msg : msg + v);
キーと現在の値に対して、新しい値を計算するラムダ式を渡します。
まだマッピングが存在しない場合はラムダ式の第二引数にnullが渡されます。
ややこしいですが、これも複数の手順を1回で済ませられます。
例えばキーの出現回数をカウントするといった状況は、ループの中はこのメソッド1行で済みます。
ラムダ式がnullを返した場合、マッピングは削除されます。
computeIfAbsent
default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) Map<String, List<String>> map = new HashMap<>(); List<String> list = map.computeIfAbsent("key", k -> new ArrayList<>());
キーに対するマッピングが存在しない場合のみ、ラムダ式を実行して値を格納します。
初めて現れた時だけコンテナを生成したいというとき、
そういうときはこちらを使えば無駄がありません。
おまけにマッピングされていたらその値を、されていなかったらラムダ式で生成した値を返します。
APIドキュメントには「もっとも一般的な用途は、次のように初期のマップされた値またはメモ化された結果として機能する新しいオブジェクトを構築することです。」と書いてありますが、そのへんの話はきしださんのページにわかりやすく書いてあります。
とても便利!
ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
初めて現れた時だけコンテナを生成したいというとき、
putIfAbsent
だとラムダ式ではないので無駄にオブジェクトが生成されてしまいます。そういうときはこちらを使えば無駄がありません。
おまけにマッピングされていたらその値を、されていなかったらラムダ式で生成した値を返します。
APIドキュメントには「もっとも一般的な用途は、次のように初期のマップされた値またはメモ化された結果として機能する新しいオブジェクトを構築することです。」と書いてありますが、そのへんの話はきしださんのページにわかりやすく書いてあります。
とても便利!
ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
computeIfPresent
default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) Map<String, String> map = new HashMap<>(); map.computeIfPresent("key", (k,v) -> v + "+");
今度は逆にマッピングされているときだけラムダ式を呼び出し、値を置き換えます。
こちらも戻り値として生成した値を返します。
ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
Map
を作る時ではなく、一度作ったMap
内のペアに対して何かの別の処理をさせたいと言うときなんかに使えそうです。こちらも戻り値として生成した値を返します。
ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
marge
default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) map.merge(key, msg, String::concat);
上のを全部合わせたような感じです。
例えば
ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
key
に対するマッピングが存在しない場合はvalue
を格納、存在する場合remappingFunctionを呼び出して返された値を格納します。例えば
String#concat
で同じキーの値を全部連結するなどが1行で書けます。ラムダ式がnullを返した場合、マッピングが削除されるのは同じです。
forEach
default void forEach(BiConsumer<? super K,? super V> action) map.forEach((k,v) -> System.out.println(k + v));
説明は不要でしょう。
Map#entrySet
からforループしてやる必要がなくなります。Collection
removeIf
default boolean removeIf(Predicate<? super E> filter)
コレクション内の要素について、ラムダ式の条件を満たすものを*全て*削除します。
他に、何度も登場してきた
Collection
はList
などの多数のインタフェースのスーパーインタフェースなので、いろんなクラスで使えます。他に、何度も登場してきた
stream
やparallelStream
メソッドもJava8で追加されたdefaultメソッドです。List
replaceAll
default void replaceAll(UnaryOperator<E> operator) List<String> list = new ArrayList<>(); : list.replaceAll(s -> s + "!");
リストの全要素に対して、ラムダ式の結果で置き換えます。
ラムダ式には元の要素が順次渡されます。
ラムダ式には元の要素が順次渡されます。
Iterable
forEach
default void forEach(Consumer<? super T> action)
「リストにforEachなかったっけ?」と思った方。
Collection
よりさらに親のjava.lang.Iterable
に実装されています。Iterable
はJava5で拡張for文を導入するときに追加されました。java.util.Iterator
とは違うので注意です。と、い、う、わ、け、で
ストリームAPIがよくわからんという方は、まずこの辺から入ってラムダ式に慣れていくといいかもしれません。
今回も以下のサイトとGoldの通常試験の参考書を参考にしています。