はじめに
- Oracle Certified Java Programmer, Silver SE 11 認定資格の受験にあたり、Java11について学習/検証した内容を資料としてまとめる。
- 本ドキュメントは、出題範囲のうち、以下出題範囲に対応する調査を行った結果となる。
- インタフェースによる抽象化/ラムダ式の理解
本ドキュメントで解説する内容
- 関数型インタフェース
- ラムダ式
- メソッド参照
- コンストラクタ参照
- Java標準ライブラリにおける関数型インタフェース
- Runnable/Callable
- Comparator#compare
- Supplier#get
- Consumer#accept
- Predicate#test
- Function#apply
- Operator#apply
関数型インタフェース
- 抽象メソッドが1つのみ定義されているインターフェース。
- ラムダ式、メソッド参照、またはコンストラクタ参照を使って関数型インタフェースのインスタンスを作成できる。
TIPS
- 関数型インタフェースにはstaticメソッドやデフォルトメソッドが含まれていても構わない(関数型インターフェースとしては無視される)
-
FunctionalInterface
アノテーションをインタフェース定義に追加すると、インタフェースが関数型インタフェースの要件を満たすかどうかを静的にチェックできる。
関数型インタフェースの例
package java.util.function;
import java.util.Objects;
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
ラムダ式
- 関数型インターフェースのメソッドを実装(オーバーライド)する記法。
- インターフェース変数にラムダ式を代入することで、関数型インタフェースのインスタンスを簡易に記述できる。
引数部 -> 本体部
TIPS
- 以下の2つの式により生成されるインスタンスは同一となる。
無名クラス
Function<Integer, String> f = new Function<>() {
@Override
public String apply(Integer i) {
return String.valueOf(i);
}
};
ラムダ式
Function<Integer, String> f = i -> String.valueOf(i);
引数部
- 引数部で定義された変数は、本体部のみで利用可能となる。
- ローカル変数と同一名称の変数を引数名に定義することはできない。
引数の数 | 記法 | 記載例 |
---|---|---|
なし | () | () -> |
1つ | (型 変数名) | (String name) -> |
^ | (変数名) | (name) -> |
^ | 変数名 | name -> |
2つ以上 | (型1 変数名1, 型2 変数名2) | (String name, int i) -> |
^ | (変数名1, 変数名2) | (name, i) -> |
本体部
- 本体部の処理において、以下の変数にアクセスできる。
- クラスのフィールド(インスタンス/クラスフィールド)
- ラムダ式の定義以前に宣言済のローカル変数のうち、finalまたは実質的finalのもの
戻り値 | 処理数 | 記法 | 記載例 |
---|---|---|---|
void | 1 | 処理を定義 | -> System.out.println("A"); |
^ | 1以上 | 各処理を{}で囲む | -> { a.hoge(); b.fuga(); } |
あり | 1 | 値を返却する処理のみ定義 | -> String.valueOf(10); |
^ | 1以上 | 各処理を{}で囲み、returnで返却 | -> { a.hoge(); return a; } |
メソッド参照
- 関数型インターフェースの変数にメソッドそのものを代入すること。
- 記法
- インスタンスメソッドの場合:
変数名::メソッド名
- staticメソッドの場合:
クラス名::メソッド名
- 自クラスのインスタンスメソッドの場合:
this::メソッド名
- インスタンスメソッドの場合:
TIPS
- 以下の2つの式で実行される内容は同一となる。
ラムダ式
List.of(1,2,3).forEach(n -> System.out.print(n)); //123
メソッド参照List.of(1,2,3).forEach(System.out::print); //123
コンストラクタ参照
- 関数型インターフェースの変数にコンストラクタを代入すること。
- 記法:
クラス名::new
TIPS
- 以下の2つの式で実行される内容は同一となる。
ラムダ式
List<Long> now = Arrays.asList(1680143332000L); now.stream().map(l -> new Date(l)).forEach(System.out::println); //Thu Mar 30 11:28:52 JST 2023
コンストラクタ参照List<Long> now = Arrays.asList(1680143332000L); now.stream().map(Date::new).forEach(System.out::println);; //Thu Mar 30 11:28:52 JST 2023
標準の関数型インタフェース
- Java標準ライブラリにおいて関数型インタフェースが提供されている。
- 代表的な関数型インタフェースを以下に示す。
package | 関数型インタフェース | 概要 |
---|---|---|
java.lang | Runnable#run | 引数なしで処理を行い、結果を返さない(検査例外なし) |
java.util.concurrent | Callable#call | 引数なしで処理を行い、結果を返さない(検査例外あり) |
java.util | Comparator#compare | 2つのオブジェクトの大小比較を行う |
java.util.function | Supplier#get | 引数なしで処理を行い、任意の結果を返す |
java.util.function | Consumer#accept | 引数ありで処理を行い、結果を返さない |
java.util.function | Predicate#test | 引数ありで処理を行い、真偽値で結果を返す(条件判定) |
java.util.function | Function#apply | 引数ありで処理を行い、任意の結果を返す |
java.util.function | UnaryOperator#apply | 引数ありで処理を行い、引数と同一の型を返す |
Runnable/Callable
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Runnable | void run() | 0 | メソッドはどのようなアクションを実行してもかまわない |
Callable<V>
|
V call() | 0 | 結果を計算するか、計算できない場合は例外をスローする |
Comparator#compare
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Comparator<T>
|
int compare(T o1, T o2) | 2 | o1がo2よりも小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数を返す |
Supplier#get
- 引数なしで処理を行い、結果を返す。
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Supplier<T>
|
T get() | 0 | 総称型(T) |
BooleanSupplier | boolean getAsBoolean | 0 | boolean |
IntSupplier | int getAsInt() | 0 | int |
LongSupplier | long getAsLong() | 0 | long |
DoubleSupplier | double getAsDouble() | 0 | double |
Consumer#accept
- 引数ありで処理を行い、結果を返さない。
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Consumer<T>
|
void accept(T t) | 1 | void |
IntConsumer | void accept(int value) | 1 | void |
LongConsumer | void accept(long value) | 1 | void |
DoubleConsumer | void accept(double value) | 1 | void |
BiConsumer<T, U>
|
void accept(T t, U u) | 2 | void |
ObjIntConsumer<T>
|
void accept(T t, int value) | 2 | void |
ObjLongConsumer<T>
|
void accept(T t, long value) | 2 | void |
ObjDoubleConsumer<T>
|
void accept(T t, double value) | 2 | void |
Predicate#test
- 引数ありで処理を行い、真偽値で結果を返す(条件判定)。
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Predicate<T>
|
boolean test(T t) | 1 | boolean |
Consumer<T>
|
boolean test(T t) | 1 | boolean |
IntPredicate | boolean test(int value) | 1 | boolean |
LongPredicate | boolean test(long value) | 1 | boolean |
DoublePredicate | boolean test(double value) | 1 | boolean |
BiPredicate<T, U>
|
boolean test(T t, U u) | 2 | boolean |
Function#apply
- 引数ありで処理を行い、結果を返す。
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
Function<T, R>
|
R apply(T t) | 1 | 総称型(R) |
IntFunction<R>
|
R apply(int value) | 1 | 総称型(R) |
LongFunction<R>
|
R apply(long value) | 1 | 総称型(R) |
DoubleFunction<R>
|
R apply(double value) | 1 | 総称型(R) |
BiFunction<T, U, R>
|
R apply(T t, U u) | 2 | 総称型(R) |
ToIntFunction<T>
|
int applyAsInt(T value) | 1 | int |
LongToIntFunction | int applyAsInt(long value) | 1 | int |
DoubleToIntFunction | int applyAsInt(double value) | 1 | int |
ToIntBiFunction<T, U>
|
int applyAsInt(T t, U u) | 2 | int |
ToLongFunction<T>
|
long applyAsLong(T value) | 1 | long |
IntToLongFunction | long applyAsLong(int value) | 1 | long |
DoubleToLongFunction | long applyAsLong(double value) | 1 | long |
ToLongBiFunction<T, U>
|
long applyAsLong(T t, U u) | 2 | long |
ToDoubleFunction<T>
|
double applyAsDouble(T value) | 1 | double |
IntToDoubleFunction | double applyAsDouble(int value) | 1 | double |
LongToDoubleFunction | double applyAsDouble(long value) | 1 | double |
ToDoubleBiFunction<T, U>
|
double applyAsDouble(T t, U u) | 2 | double |
Operator#apply
- 引数ありで処理を行い、引数と同一の型を返す。
関数型インタフェース | メソッド | 引数の数 | 戻り値 |
---|---|---|---|
UnaryOperator<T>
|
T apply(T t) | 1 | 総称型(T) |
IntUnaryOperator | T applyAsInt(int operand) | 1 | int |
LongUnaryOperator | T applyAsLong(long operand) | 1 | long |
DoubleUnaryOperator | T applyAsDouble(double operand) | 1 | double |
BinaryOperator<T>
|
T apply(T t, T u) | 2 | 総称型(T) |