CUBは子供の白熊

Java SE 8 実践プログラミングの練習問題を解く

第1章 ラムダ式とは : 問題 9 : デフォルトメソッド

問題 9

CollectionのサブインターフェースCollection2を作成して、デフォルトメソッド

void forEachIf(Consumer<T> action, Predicate<T> filter)

を追加せよ
このメソッドは、filtertrueを返した個々の要素に対してactionを適用する

解答

Collection2インターフェースの実装は、以下のとおり

public interface Collection2<T> extends Collection<T> {
    default void forEachIf(Consumer<T> action, Predicate<T> filter) {
        forEach(
            (T t) -> {
                if (filter.test(t))
                    action.accept(t);
            }
        );
    }
}

さらに問題

どのような場面で、このメソッドを活用できるか?

解答

Collection2を実装する具象クラスを定義しないといけないので、活用できる場面はない。 … まさか、こんな落ち?

例えばListの場合は型が違うというコンパイルエラーになる。

List<Integer> list = Arrays.asList(1, 10, null, 5);
list.forEachIf(System.out::println, (t) -> t != null);    // コンパイルエラー

キャストすれば、デフォルトメソッドを呼んでくれるかと期待したが

List<Integer> list = Arrays.asList(1, 10, null, 5);
((Collection2<Integer>)list).forEachIf(System.out::println, (t) -> t != null);

ClassCastExceptionであえなく撃沈した。