引数の数とタイプが異なるAction
デリゲート(Java Consumer
機能的インターフェースと同等)のいくつかの実装を提供する.Netなど)では、Java 8は、異なるタイプの複数の引数でConsumer
を指定する方法を提供します。
Javaでは、ジェネリック型パラメーターが異なるだけで、同じ名前の異なる型を定義することはできませんが、複数の引数Consumer
を提供するための流な代替手段があります。
新しい機能的なインターフェースを定義する必要のない簡単な方法はありますか?
3つ以上の引数には、最後のコンシューマーでcurried( http://en.wikipedia.org/wiki/Currying )関数を使用できます。
Function<Double, Function<Integer, Consumer<String>>> f = d -> i -> s -> {
System.out.println("" + d+ ";" + i+ ";" + s);
};
f.apply(1.0).apply(2).accept("s");
出力は次のとおりです。
1.0;2;s
任意の数の引数の関数を表すには、1つの引数の関数があれば十分です。 https://en.wikipedia.org/wiki/Currying#Lambda_calculi
デフォルトでは、Java.util.function.Consumer
とJava.util.function.BiConsumer
のみに制限されています。現在のJavaストリーミングAPIには十分です。ただし、必要な数の引数を受け取り、独自のカスタムAPIで使用する独自の機能インターフェイスを作成できます。
機能インターフェースを自分で定義するのは非常に簡単です。私が現在取り組んでいるプロジェクトでは、引数としてメソッドを渡すことでコードをNiceとDRYに保つことができる場合がいくつかありました。定義した機能インターフェイスは次のとおりです。
@FunctionalInterface
public interface CheckedVoidFunction {
void apply() throws Exception;
}
@FunctionalInterface
public interface VoidFunction {
void apply();
}
@FunctionalInterface
public interface SetCategoryMethod {
void accept(ObservableList<IRegionWithText> list, Document document, String pattern);
}
これらの種類の引数を受け入れるメソッドは次のとおりです。
private void loadAnnotations(String annotationType, VoidFunction afterLoadFunction, List<Path> documentPaths) {
そして、ここに、異なるメソッドを引数としてこれらのメソッドを呼び出す場所があります。
loadAnnotations(DocumentReader.REDACTION_ANNOTATION_TYPE, this::afterLoadRedactions, documentPaths);
loadAnnotations(DocumentReader.HIGHLIGHT_ANNOTATION_TYPE, this::afterLoadHighlights, documentPaths);
これを行うためのより良い方法があるかもしれませんが、私は私にとって有用だったことを共有したいと思いました。
新しい機能的なインターフェースを定義する必要のない簡単な方法はありますか?
オブジェクトには、他のオブジェクトをいくつでも含めることができます。 Streams APIは、一度に1つのオブジェクトのみをストリーミングするように設計されています。さらに必要な場合は、それらをすべて保持するオブジェクトにラップします。
例えば.
Map<String, Long> map = new HashMap<>();
// each entry has a key and a value as Map.Entry<String, Long>
Map<Long, String> revMap = map.entrySet().stream()
.collect(groupingBy(Entry::getValue(), HashMap::new, Entry::getKey));