Java8でメソッド参照をFunctionオブジェクトとして使用してそのメソッドを使用する方法はありますか?
Stream.of("ciao", "hola", "hello")
.map(String::length.andThen(n -> n * 2))
この質問は とは関係ありませんStream。例として使用されています。メソッド リファレンスについて回答をお願いします。
Java8でメソッド参照をFunctionオブジェクトとして使用してそのメソッドを使用する方法はありますか?
Stream.of("ciao", "hola", "hello")
.map(String::length.andThen(n -> n * 2))
この質問は とは関係ありませんStream。例として使用されています。メソッド リファレンスについて回答をお願いします。
これを行う静的メソッドを作成できます。
import java.util.function.*;
class Test {
public static void main(String[] args) {
Function<String, Integer> function = combine(String::length, n -> n * 2);
System.out.println(function.apply("foo"));
}
public static <T1, T2, T3> Function<T1, T3> combine(
Function<T1, T2> first,
Function<T2, T3> second) {
return first.andThen(second);
}
}
次に、それをユーティリティ クラスに配置して、静的にインポートできます。
または、与えられた関数を返すだけの単純な静的メソッドを作成して、コンパイラが何をしているのかを認識できるようにします。
import java.util.function.*;
class Test {
public static void main(String[] args) {
Function<String, Integer> function = asFunction(String::length).andThen(n -> n * 2);
System.out.println(function.apply("foo"));
}
public static <T1, T2> Function<T1, T2> asFunction(Function<T1, T2> function) {
return function;
}
}
キャストを使用して、インラインで目的を達成できるはずです。
Stream.of("ciao", "hola", "hello")
.map(((Function<String, Integer>) String::length).andThen(n -> n * 2))
コンパイラには「タイプヒント」しかないため、実際にはオブジェクトを「キャスト」せず、実際のキャストのオーバーヘッドはありません。
または、読みやすくするためにローカル変数を使用できます。
Function<String, Integer> fun = String::length
Stream.of("ciao", "hola", "hello")
.map(fun.andThen(n -> n * 2));
より簡潔な 3 つ目の方法は、ユーティリティ メソッドを使用することです。
public static <T, X, U> Function<T, U> chain(Function<T, X> fun1, Function<X, U> fun2)
{
return fun1.andThen(fun2);
}
Stream.of("ciao", "hola", "hello")
.map(chain(String::length, n -> n * 2));
これはテストされていないことに注意してください。したがって、この場合に型推論が正しく機能するかどうかはわかりません。
使用することもできます
Function.identity().andThen(String::length).andThen(n -> n * 2)
問題は、String::length必ずしもFunction;ではないことです。多くの機能的インターフェースに適合できます。これは、ターゲット タイプを提供するコンテキストで使用する必要があり、コンテキストは代入、メソッド呼び出し、キャストなどです。
Functionターゲットの型付けのためだけに静的メソッドを提供できる場合は、次のことができます。
Function.by(String::length).andThen(n->n*2)
static <T, R> Function<T, R> by(Function<T, R> f){ return f; }
static <T> AsyncIterator<T> by(AsyncIterator<T> asyncIterator)
ラムダ式またはメソッド参照から AsyncIterator を作成する構文シュガー。
このメソッドは単に引数 を返しますが
asyncIterator、これは少し奇妙に思えます。説明:AsyncIterator は関数型インターフェースであるため、インスタンスはラムダ式またはメソッド参照によって 3 つのコンテキストで作成できます。
// Assignment Context
AsyncIterator<ByteBuffer> asyncIter = source::read;
asyncIter.forEach(...);
// Casting Context
((AsyncIterator<ByteBuffer>)source::read)
.forEach(...);
// Invocation Context
AsyncIterator.by(source::read)
.forEach(...);
3 番目のオプションは他の 2 つよりも見栄えがよく、それがこの方法の目的です。
キャストを使用できます
Stream.of("ciao", "hola", "hello")
.map(((Function<String, Integer>) String::length)
.andThen(n -> n * 2))
.forEach(System.out::println);
版画
8
8
10