Java SE 11 Gold 自分用メモ(2)

  1. java.util.functionパッケージの関数型インタフェースのうち、名前が「Bi」で始まっているものは、「Bi」を取り去った名前の関数型インタフェースが、引数を2つ受け取り、それらを処理に使用するように変わったもの(命名パターンに関しての例外:UnaryOperatorとBinaryOperator)
  2. 関数型インタフェースjava.util.function.Supplierを使用する例
    Supplier<List<String>> sup = () -> new ArrayList<String>();
    List<String> s = sup.get();
    1行目はメソッド参照を使って以下のように書くことも可能
    Supplier<List<String>> sup = ArrayList<String>::new;
  3. 関数型インタフェースjava.util.function.Consumerを使用する例
    Consumer<String> con = (str) -> {
    	System.out.println("Consumer is processing");
    	System.out.println(str);
    	System.out.println("Consumer finished processing");
    };
    con.accept("Hello, world");
  4. 関数型インタフェースjava.util.function.Predicateを使用する例(predicateは「断定する」の意)
    Predicate<String> pre = str -> {
    	return str.length() > 10;
    };
    boolean b = pre.test("internationalization");
  5. 関数型インタフェースjava.util.function.Predicateのデフォルトメソッドorとandにより、testメソッドで与えた引数に対して複雑な論理演算を実行可能
    Predicate<Integer> isMultipleOf7 = n -> n % 7 == 0;
    Predicate<Integer> isEven = n -> n % 2 == 0;
    Predicate<Integer> isLessThan5 = n -> n > 5;
    boolean res = isMultipleOf7.or(isEven.and(isLessThan5)).test(4);
    // 7の倍数である || (偶数である && 5未満である)
  6. 関数型インタフェースjava.util.function.Functionを使用する例
    Function<Long, String> fun = (num) -> num + " yen";
    String price = fun.apply(360L);
  7. 関数型インタフェースjava.util.function.FunctionのデフォルトメソッドandThenとcomposeにより、applyメソッドで与えた引数に対して複数の処理をまとめて実行可能(andThenが順次、composeが逆順)
    Function<Integer, Integer> f = (num) -> num + 1;
    Function<Integer, Integer> g = (num) -> num * 2;
    System.out.println(f.andThen(g).apply(5));
    // 5 + 1 を実行後、 6 * 2 ゆえ12
    System.out.println(f.compose(g).apply(5));
    // 5 * 2 を実行後、 10 + 1 ゆえ11
  8. java.util.function.UnaryOperatorインタフェースはFunctionを継承したもので、applyメソッドの引数と返り値を同じ型にしたい場合に使用する(BinaryOperatorとBiFunctionの関係も同様で、applyメソッドが受け取る2つの引数と返り値の型が全て同じである場合に使用、ただしBinaryOperatorが受け取る型ジェネリクスは1つだけを指定するので注意)
  9. java.util.Listをはじめとするコレクション型の要素1つ1つに対し、型を変えることのない同一の処理を行いたい場合にUnaryOperatorが役立つ(以下サンプル参照)
    List<String> l = new ArrayList<String>();
    l.add("alice");
    l.add("bob");
    l.add("charles");
    l.replaceAll(str -> str.toUpperCase());
    // replaceAllメソッドにUnaryOperatorを渡す
    System.out.println(l);
    // [ALICE, BOB, CHARLES]