java.util.function パッケージ以下にある関数インターフェースの使い方をメモする。
Function<T, R>
apply(T)
package java8sample;
import java.util.function.Function;
public class Java8Sample {
public static void main(String[] args) {
Function<String, Integer> function = string -> Integer.parseInt(string);
System.out.println(function.apply("12345"));
}
}
12345
Function<T, R> の抽象メソッド。
T 型の引数を受け取って、 R 型の値を返す処理を実装する。
compose(Function<? super V,? extends T>)
package java8sample;
import java.util.function.Function;
public class Java8Sample {
public static void main(String[] args) {
Function<String, String> wrapDoubleQuotation = str -> "\"" + str + "\"";
Function<String, String> wrapSingleQuotation = str -> "'" + str + "'";
Function<String, String> wrapDoubleAndSingleQuotation = wrapDoubleQuotation.compose(wrapSingleQuotation);
String result = wrapDoubleAndSingleQuotation.apply("hoge");
System.out.println(result);
}
}
"'hoge'"
compose() メソッドを実行した Function オブジェクトに、引数で渡した Function オブジェクトを組み合わせた新しい Function オブジェクトが生成される。
↑の実装は、↓の実装と同じ意味になる。
package java8sample;
import java.util.function.Function;
public class Java8Sample {
public static void main(String[] args) {
Function<String, String> wrapDoubleQuotation = str -> "\"" + str + "\"";
Function<String, String> wrapSingleQuotation = str -> "'" + str + "'";
String result = wrapDoubleQuotation.apply(wrapSingleQuotation.apply("hoge"));
System.out.println(result);
}
}
compose(...) メソッドに渡した Function オブジェクトが実行され、その結果が元の Function オブジェクトに渡される。
andThen(Function<? super R,? extends V>)
package java8sample;
import java.util.function.Function;
public class Java8Sample {
public static void main(String[] args) {
Function<String, String> wrapDoubleQuotation = str -> "\"" + str + "\"";
Function<String, String> wrapSingleQuotation = str -> "'" + str + "'";
Function<String, String> wrapDoubleAndSingleQuotation = wrapDoubleQuotation.andThen(wrapSingleQuotation);
String result = wrapDoubleAndSingleQuotation.apply("hoge");
System.out.println(result);
}
}
'"hoge"'
compose() の逆順序で Function オブジェクトが適用される。
identity()
package java8sample;
import java.util.function.Function;
public class Java8Sample {
public static void main(String[] args) {
Function<String, String> function = Function.identity();
System.out.println(function.apply("string message"));
}
}
string message
static メソッド。
apply(T) メソッドに渡した値をそのまま返す Function オブジェクトを生成する。
用途はよくわからない。
UnaryOperator<T>
Function の拡張インターフェース。
Function の型引数が2つとも同じ型、つまり、引数も戻り値も同じ型を返す特別パターンの Function。
package java8sample;
import java.util.function.UnaryOperator;
public class Java8Sample {
public static void main(String[] args) {
UnaryOperator<String> unary = string -> "[" + string + "]";
System.out.println(unary.apply("hoge"));
}
}
[hoge]
Consumer<T>
accept(T)
package java8sample;
import java.util.function.Consumer;
public class Java8Sample {
public static void main(String[] args) {
Consumer<String> consumer = string -> System.out.println("Cunsumer : " + string);
consumer.accept("hoge");
}
}
Cunsumer : hoge
Consumer<T> の抽象メソッド。
T 型の値を引数に受け取って、戻り値無しの処理を実装する。
consumer の意味は、「消費者」。
戻り値を返さず引数を 消費するだけ という感じ?
andThen(Consumer<? super T>)
package java8sample;
import java.util.function.Consumer;
public class Java8Sample {
public static void main(String[] args) {
Consumer<String> hoge = string -> System.out.println("hoge : " + string);
Consumer<String> fuga = string -> System.out.println("fuga : " + string);
Consumer<String> piyo = hoge.andThen(fuga);
piyo.accept("piyo");
}
}
hoge : piyo
fuga : piyo
「andThen() メソッドを実行した Consumer オブジェクト」→「引数で渡した Consumer オブジェクト」の順序で処理を実行する新しい Consumer オブジェクトが生成される。
Supplier<T>
get()
package java8sample;
import java.util.function.Supplier;
public class Java8Sample {
public static void main(String[] args) {
Supplier<String> supplier = () -> "hoge";
System.out.println(supplier.get());
}
}
hoge
Supplier<T> の抽象メソッド。
T 型の値を返す処理を実装する。
supplier の意味は、「供給者」。
Predicate<T>
test(T)
package java8sample;
import java.util.function.Predicate;
public class Java8Sample {
public static void main(String[] args) {
Predicate<String> predicate = string -> string.isEmpty();
System.out.println(predicate.test(""));
System.out.println(predicate.test("hoge"));
}
}
true
false
Predicate<T> の抽象メソッド。
T 型の値を引数に受け取って、 boolean の値を返す処理を実装する。
predicate の意味は「断言する」「断定する」。
値の検証を明示するのに使う感じかと。
isEqual(Object)
package java8sample;
import java.util.function.Predicate;
public class Java8Sample {
public static void main(String[] args) {
Predicate<String> isHoge = Predicate.isEqual("hoge");
System.out.println(isHoge.test("hoge"));
System.out.println(isHoge.test("fuga"));
Predicate<Object> isNull = Predicate.isEqual(null);
System.out.println(isNull.test(null));
System.out.println(isNull.test("not null"));
}
}
true
false
true
false
引数で受け取ったオブジェクトと等しいかどうかを判定する新しい Predicate オブジェクトを生成する(比較は Object#equals(Object) メソッドが使用される)。
null セーフになっている。
and(Predicate<? super T>)
package java8sample;
import java.util.function.Predicate;
public class Java8Sample {
public static void main(String[] args) {
Predicate<String> isUpperCase = string -> string.matches("[A-Z]+");
Predicate<String> isAlphabet = string -> string.matches("[a-zA-Z]+");
Predicate<String> predicate = isAlphabet.and(isUpperCase);
System.out.println(predicate.test("HOGE"));
System.out.println(predicate.test("hoge"));
}
}
true
false
引数で渡した Predicate オブジェクトを AND 条件で連結させた新しい Predicate オブジェクトを生成する。
or(Predicate<? super T>)
package java8sample;
import java.util.function.Predicate;
public class Java8Sample {
public static void main(String[] args) {
Predicate<String> isUpperCase = string -> string.matches("[A-Z]+");
Predicate<String> isNumber = string -> string.matches("\\d+");
Predicate<String> predicate = isNumber.or(isUpperCase);
System.out.println(predicate.test("HOGE"));
System.out.println(predicate.test("1234"));
System.out.println(predicate.test("hoge"));
}
}
true
true
false
引数で渡した Predicate オブジェクトを OR 条件で連結させた新しい Predicate オブジェクトを生成する。
negate()
package java8sample;
import java.util.function.Predicate;
public class Java8Sample {
public static void main(String[] args) {
Predicate<String> isEmpty = string -> string.isEmpty();
Predicate<String> isNotEmpty = isEmpty.negate();
System.out.println(isNotEmpty.test("hoge"));
System.out.println(isNotEmpty.test(""));
}
}
true
false
negate() を実行した Predicate オブジェクトを否定する、新しい Predicate オブジェクトが生成される。
Bi~
BiConsumer<T,U>BiFunction<T,U,R>BiPredicate<T,U>
それぞれ Consumer<T> ・ Function<T, R> ・ Predicate<T, U> の抽象メソッドの引数が2つになっている。
BinaryOperator<T>
BiFunction の拡張インターフェース。
T 型の引数を 2 つ受け取って T 型の値を返す apply(T, T) メソッドが抽象メソッドとして存在する。
maxBy(Comparator<? super T>)
package java8sample;
import java.util.function.BinaryOperator;
public class Java8Sample {
public static void main(String[] args) {
BinaryOperator<Integer> maxBy = BinaryOperator.maxBy(Integer::compare);
int max = maxBy.apply(21, 10);
System.out.println(max);
}
}
21
apply(T, T) メソッドに渡された2値を、指定した Comparator オブジェクトで比較して大きい方の値を返す BinaryOperator オブジェクトを生成する。
minBy(Comparator<? super T>)
package java8sample;
import java.util.function.BinaryOperator;
public class Java8Sample {
public static void main(String[] args) {
BinaryOperator<Integer> minBy = BinaryOperator.minBy(Integer::compare);
int min = minBy.apply(21, 10);
System.out.println(min);
}
}
10
maxBy() の逆。
To~Function と To~BiFunction
ToIntFunction<T>ToLongFunction<T>ToDoubleFunction<T>
それぞれ、 T 型の値を引数に受け取って、プリミティブ型の値を返す applyAs~(T) 抽象メソッドを持つ。
package java8sample;
import java.util.function.ToIntFunction;
public class Java8Sample {
public static void main(String[] args) {
ToIntFunction<String> getLength = string -> string.length();
System.out.println(getLength.applyAsInt("hoge"));
}
}
4
ToIntBiFunction<T,U>ToLongBiFunction<T,U>ToDoubleBiFunction<T,U>
それぞれ、 To~Function の引数が 2 つになったバージョン。
package java8sample;
import java.util.function.ToIntBiFunction;
public class Java8Sample {
public static void main(String[] args) {
ToIntBiFunction<Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.applyAsInt(12, 53));
}
}
65
~To***Function
IntToDoubleFunctionDoubleToIntFunctionLongToDoubleFunctionDoubleToLongFunctionIntToLongFunctionLongToIntFunction
それぞれ ~ を受け取って *** を返す applyAs***(~) メソッドを抽象メソッドとして持つ。
package java8sample;
import java.util.function.IntToDoubleFunction;
public class Java8Sample {
public static void main(String[] args) {
IntToDoubleFunction function = i -> (double)i;
System.out.println(function.applyAsDouble(20));
}
}
20.0
Obj~Consumer
ObjIntConsumer<T>ObjLongConsumer<T>ObjDoubleConsumer<T>
それぞれ T 型の値と ~ の値を引数に受け取る accept(T, ~) メソッドを抽象メソッドとして持つ。
package java8sample;
import java.util.Arrays;
import java.util.List;
import java.util.function.ObjIntConsumer;
public class Java8Sample {
public static void main(String[] args) {
List<String> list = Arrays.asList("hoge", "fuga", "piyo");
forEach(list, (value, index) -> {
System.out.printf("list[%d] = %s%n", index, value);
});
}
public static <T> void forEach(List<T> list, ObjIntConsumer<T> callback) {
for (int i=0; i<list.size(); i++) {
callback.accept(list.get(i), i);
}
}
}
list[0] = hoge
list[1] = fuga
list[2] = piyo