In Java, is it possible to have a lambda accept multiple different types?
在Java中,是否可以让lambda接受多种不同的类型?
I.e: Single variable works:
即:单变量有效:
Function <Integer, Integer> adder = i -> i + 1;
System.out.println (adder.apply (10));
Varargs also work:
Varargs也有效:
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 })));
But I want something that can accept many different types of arguments, e.g:
但我想要一些可以接受许多不同类型参数的东西,例如:
Function <String, Integer, Double, Person, String> myLambda = a , b, c, d-> {
[DO STUFF]
return "done stuff"
};
The main use is to have small inline functions inside functions for convenience.
主要用途是在函数内部使用小内联函数以方便使用。
I've looked around google and inspected Java's Function Package, but could not find. Is this possible?
我查看了谷歌并检查了Java的功能包,但找不到。这可能吗?
[SOLVED, Thanks!]
@Sotirios Delimanolis's way of implementing an interface(s) works for me.
@Sotirios Delimanolis实现界面的方式对我有用。
Based on his syntax, I made this simplified working example. (if of use to anyone reading...) I noticed that you have to name the interface something other than 'Function' as this *es with the built-in java.util.Function.
基于他的语法,我做了这个简化的工作示例。 (如果用于任何人阅读...)我注意到你必须将界面命名为“函数”以外的东西,因为这与内置的java.util.Function冲突。
public class main {
@FunctionalInterface
interface Function3 <A, B, C, R> {
//R is like Return, but doesn't have to be last in the list nor named R.
public R apply (A a, B b, C c);
}
public static void main (String [] args) {
Function3 <String, Integer, Double, Double> multiAdder = (a, b, c) -> {
return Double.parseDouble (a) + b + c;
};
System.out.println (multiAdder.apply ("22.4", 2, 40.0));
}
}
I'll just implement a bunch of interfaces, one with 3 args, one with 4 etc..
我将实现一堆接口,一个有3个args,一个有4个等。
5 个解决方案
#1
105
It's possible if you define such a functional interface with multiple type parameters. There is no such built in type. (There are a few limited types with multiple parameters.)
如果您使用多个类型参数定义这样的功能接口,则可能。没有这种内置类型。 (有一些有限的类型有多个参数。)
@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';
}
There's also no way to define a variable number of type parameters, if that's what you were asking about.
如果这就是你所询问的,那么也无法定义可变数量的类型参数。
Some languages, like Scala, define a number of built in such types, with 1, 2, 3, 4, 5, 6, etc. type parameters.
某些语言(如Scala)定义了许多内置的类型,包括1,2,3,4,5,6等类型参数。
#2
18
For something with 2 parameters, you could use BiFunction
. If you need more, you can define your own function interface, like so:
对于具有2个参数的东西,您可以使用BiFunction。如果您需要更多,可以定义自己的功能界面,如下所示:
@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
public R apply(T t, U u, V v, W w);
}
If there is more than one parameter, you need to put parentheses around the argument list, like so:
如果有多个参数,则需要在参数列表周围加上括号,如下所示:
FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
// do something
return "done something";
};
#3
16
For this case you could use interfaces from default library (java 1.8):
对于这种情况,您可以使用默认库(java 1.8)中的接口:
java.util.function.BiConsumer
java.util.function.BiFunction
There is a small (not the best) example of default method in interface:
接口中有一个小的(不是最好的)默认方法示例:
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 "";
};
}}
#4
1
Another alternative, not sure if this applies to your particular problem but to some it may be applicable is to use UnaryOperator
in java.util.function library. where it returns same type you specify, so you put all your variables in one class and is it as a parameter:
另一种选择,不确定这是否适用于您的特定问题,但对于某些可能适用的是在java.util.function库中使用UnaryOperator。它返回您指定的相同类型,因此您将所有变量放在一个类中,并将其作为参数:
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;
}
}
So the class you have, in this case Person
, can have numerous instance variables and won't have to change the parameter of your lambda expression.
因此,您拥有的类(在本例中为Person)可以包含许多实例变量,而不必更改lambda表达式的参数。
For those interested, I've written notes on how to use java.util.function library: http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
对于那些感兴趣的人,我写了关于如何使用java.util.function库的笔记:http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
#5
0
You could also use jOOL library - https://github.com/jOOQ/jOOL
您也可以使用jOOL库 - https://github.com/jOOQ/jOOL
It has already prepared function interfaces with different number of parameters. For instance, you could use org.jooq.lambda.function.Function3
, etc from Function0
up to Function16
.
它已经准备好了具有不同数量参数的功能接口。例如,您可以使用从Function0到Function16的org.jooq.lambda.function.Function3等。
#1
105
It's possible if you define such a functional interface with multiple type parameters. There is no such built in type. (There are a few limited types with multiple parameters.)
如果您使用多个类型参数定义这样的功能接口,则可能。没有这种内置类型。 (有一些有限的类型有多个参数。)
@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';
}
There's also no way to define a variable number of type parameters, if that's what you were asking about.
如果这就是你所询问的,那么也无法定义可变数量的类型参数。
Some languages, like Scala, define a number of built in such types, with 1, 2, 3, 4, 5, 6, etc. type parameters.
某些语言(如Scala)定义了许多内置的类型,包括1,2,3,4,5,6等类型参数。
#2
18
For something with 2 parameters, you could use BiFunction
. If you need more, you can define your own function interface, like so:
对于具有2个参数的东西,您可以使用BiFunction。如果您需要更多,可以定义自己的功能界面,如下所示:
@FunctionalInterface
public interface FourParameterFunction<T, U, V, W, R> {
public R apply(T t, U u, V v, W w);
}
If there is more than one parameter, you need to put parentheses around the argument list, like so:
如果有多个参数,则需要在参数列表周围加上括号,如下所示:
FourParameterFunction<String, Integer, Double, Person, String> myLambda = (a, b, c, d) -> {
// do something
return "done something";
};
#3
16
For this case you could use interfaces from default library (java 1.8):
对于这种情况,您可以使用默认库(java 1.8)中的接口:
java.util.function.BiConsumer
java.util.function.BiFunction
There is a small (not the best) example of default method in interface:
接口中有一个小的(不是最好的)默认方法示例:
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 "";
};
}}
#4
1
Another alternative, not sure if this applies to your particular problem but to some it may be applicable is to use UnaryOperator
in java.util.function library. where it returns same type you specify, so you put all your variables in one class and is it as a parameter:
另一种选择,不确定这是否适用于您的特定问题,但对于某些可能适用的是在java.util.function库中使用UnaryOperator。它返回您指定的相同类型,因此您将所有变量放在一个类中,并将其作为参数:
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;
}
}
So the class you have, in this case Person
, can have numerous instance variables and won't have to change the parameter of your lambda expression.
因此,您拥有的类(在本例中为Person)可以包含许多实例变量,而不必更改lambda表达式的参数。
For those interested, I've written notes on how to use java.util.function library: http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
对于那些感兴趣的人,我写了关于如何使用java.util.function库的笔记:http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
#5
0
You could also use jOOL library - https://github.com/jOOQ/jOOL
您也可以使用jOOL库 - https://github.com/jOOQ/jOOL
It has already prepared function interfaces with different number of parameters. For instance, you could use org.jooq.lambda.function.Function3
, etc from Function0
up to Function16
.
它已经准备好了具有不同数量参数的功能接口。例如,您可以使用从Function0到Function16的org.jooq.lambda.function.Function3等。