Javaでは、ラムダが複数の異なる型を受け付けるようにすることは可能ですか?
I.e:単一の変数が機能する:
Function <Integer, Integer> adder = i -> i + 1;
System.out.println (adder.apply (10));
可変引数も機能します。
Function <Integer [], Integer> multiAdder = ints -> {
int sum = 0;
for (Integer i : ints) {
sum += i;
}
return sum;
};
//....
System.out.println ((multiAdder.apply (new Integer [] { 1, 2, 3, 4 })));
しかし、私はいろいろな種類の議論を受け入れることができる何かが欲しいです。
Function <String, Integer, Double, Person, String> myLambda = a , b, c, d-> {
[DO STUFF]
return "done stuff"
};
主な用途は、便宜上、関数内に小さなインライン関数を持つことです。
私はグーグルを見回し、Javaの関数パッケージを調べましたが、見つけることができませんでした。これは可能ですか?
このような機能的インターフェースを複数の型パラメーターで定義すれば可能です。そのような内蔵型はありません。 (複数のパラメータを持つ限られたタイプがいくつかあります。)
@FunctionalInterface
interface Function<One, Two, Three, Four, Five, Six> {
public Six apply(One one, Two two, Three three, Four four, Five five);
}
public static void main(String[] args) throws Exception {
Function<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}
それがあなたが尋ねていたものであるならば、可変数の型パラメータを定義する方法もありません。
Scalaのようないくつかの言語は、1、2、3、4、5、6などの型パラメータを使って、そのような型の組込みをいくつか定義しています。
2つのパラメータを持つものでは、BiFunction
を使うことができます。さらに必要な場合は、次のように独自の関数インタフェースを定義できます。
@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
public R apply(T t, U u, V v, W w);
}
複数のパラメータがある場合は、引数リストを括弧で囲む必要があります。
FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
// do something
return "done something";
};
この場合は、デフォルトのライブラリ(Java 1.8)のインタフェースを使用できます。
Java.util.function.BiConsumer
Java.util.function.BiFunction
インターフェースのデフォルトメソッドの小さな(最良ではない)例があります。
default BiFunction<File, String, String> getFolderFileReader() {
return (directory, fileName) -> {
try {
return FileUtils.readFile(directory, fileName);
} catch (IOException e) {
LOG.error("Unable to read file {} in {}.", fileName, directory.getAbsolutePath(), e);
}
return "";
};
}}
JOOLライブラリを使うこともできます - https://github.com/jOOQ/jOOL
それはすでに異なった数のパラメータを持つ関数インターフェースを用意しています。たとえば、org.jooq.lambda.function.Function3
からFunction0
までのFunction16
などを使用できます。
もう1つの選択肢は、これがあなたの特定の問題に当てはまるかどうかわからないが、それが当てはまるかもしれないいくつかの問題に、Java.util.functionライブラリのUnaryOperator
を使うことです。ここでは、指定したのと同じ型が返されるので、すべての変数を1つのクラスにまとめて、それをパラメータとして使用します。
public class FunctionsLibraryUse {
public static void main(String[] args){
UnaryOperator<People> personsBirthday = (p) ->{
System.out.println("it's " + p.getName() + " birthday!");
p.setAge(p.getAge() + 1);
return p;
};
People mel = new People();
mel.setName("mel");
mel.setAge(27);
mel = personsBirthday.apply(mel);
System.out.println("he is now : " + mel.getAge());
}
}
class People{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
ですから、あなたが持っているクラス、この場合Person
は、たくさんのインスタンス変数を持つことができ、ラムダ式のパラメータを変更する必要はありません。
興味のある方のために、私はJava.util.functionライブラリの使い方についてのメモを書きました。 http://sysdotoutdotprint.com/index.php/2017/04/28/Java-util-function-library/
ラムダを利用するには:3種類の操作があります。
1。パラメーターを受け入れる - > Consumer
2。テストパラメータの戻り値 - >述語
3。パラメータ操作と戻り値の操作 - >機能
Javaの関数型インタフェース最大2つのパラメータ:
単一パラメータインタフェース
消費者
述語
関数
2パラメータインタフェース
BiConsumer
BiPredicate
バイファンクション
つ以上の場合、あなたは以下のように機能的なインターフェースを作成しなければなりません(消費者タイプ):
@FunctionalInterface
public interface FiveParameterConsumer<T, U, V, W, X> {
public void accept(T t, U u, V v, W w, X x);
}
OOTB解決策は、package kotlin.jvm.functions
、Function0
、Function1
... Function2
を定義するFunction22
をインポートすることです。
例えば。、
import kotlin.jvm.functions.*;
public void testFunction() {
Function3<Integer, Integer, Integer, Integer> f3 = (x, y, z) -> x + y + z;
System.out.println(f3.invoke(1, 2, 3));
Function4<Integer, Integer, Integer, Integer, Integer> f4 = (a, b, c, d) -> a + b + c + d;
System.out.println(f4.invoke(1, 2, 3, 4));
}
scala
にも同様の機能があります。