java lambda 可以有超过 1 个参数吗?
Can a java lambda have more than 1 parameter?
在 Java 中,是否可以让 lambda 接受多种不同的类型?
即:
单变量有效:
Function <Integer, Integer> adder = i -> i + 1;
System.out.println (adder.apply (10));
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 })));
但我想要一些可以接受多种不同类型参数的东西,例如:
Function <String, Integer, Double, Person, String> myLambda = a , b, c, d-> {
[DO STUFF]
return "done stuff"
};
主要用途是为了方便在函数内部有小的内联函数。
我环顾了 google 并检查了 Java 的功能包,但没有找到。这可能吗?
如果您定义这样一个具有多个类型参数的功能接口,这是可能的。没有这样的内置类型。 (有一些具有多个参数的有限类型。)
@FunctionalInterface
interface Function6<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 {
Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}
我在这里称它为Function6
。该名称由您自行决定,只是尽量不要与 Java 库中的现有名称冲突。
也没有办法定义可变数量的类型参数,如果这就是您要问的问题。
一些语言,如 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 "";
};
}}
另一种选择,不确定这是否适用于您的特定问题,但可能适用于某些问题,是在 java.util.function 库中使用 UnaryOperator
。
它 returns 与您指定的类型相同,因此您将所有变量放在一个 class 中并将其作为参数:
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;
}
}
所以您拥有的 class,在本例中 Person
,可以有许多实例变量,并且不必更改 lambda 表达式的参数。
对于那些感兴趣的人,我写了关于如何使用 java.util.function 库的笔记:http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
您也可以使用 jOOL 库 - https://github.com/jOOQ/jOOL
已经准备好不同参数个数的函数接口。例如,您可以使用 org.jooq.lambda.function.Function3
,等等,从 Function0
到 Function16
。
要使用 lambda :有三种类型的操作:
1. 接受参数 --> Consumer
2.测试参数return boolean --> Predicate
3. 操作参数和return值 --> Function
Java函数接口最多两个参数:
单参数接口
消费者
谓词
函数
双参数接口
双消费者
双谓词
双函数
如果超过两个,您必须创建功能接口如下(消费者类型):
@FunctionalInterface
public interface FiveParameterConsumer<T, U, V, W, X> {
public void accept(T t, U u, V v, W w, X x);
}
一些 lambda 函数:
import org.junit.Test;
import java.awt.event.ActionListener;
import java.util.function.Function;
public class TestLambda {
@Test
public void testLambda() {
System.out.println("test some lambda function");
////////////////////////////////////////////
//1-any input | any output:
//lambda define:
Runnable lambda1 = () -> System.out.println("no parameter");
//lambda execute:
lambda1.run();
////////////////////////////////////////////
//2-one input(as ActionEvent) | any output:
//lambda define:
ActionListener lambda2 = (p) -> System.out.println("One parameter as action");
//lambda execute:
lambda2.actionPerformed(null);
////////////////////////////////////////////
//3-one input | by output(as Integer):
//lambda define:
Function<String, Integer> lambda3 = (p1) -> {
System.out.println("one parameters: " + p1);
return 10;
};
//lambda execute:
lambda3.apply("test");
////////////////////////////////////////////
//4-two input | any output
//lambda define:
TwoParameterFunctionWithoutReturn<String, Integer> lambda4 = (p1, p2) -> {
System.out.println("two parameters: " + p1 + ", " + p2);
};
//lambda execute:
lambda4.apply("param1", 10);
////////////////////////////////////////////
//5-two input | by output(as Integer)
//lambda define:
TwoParameterFunctionByReturn<Integer, Integer> lambda5 = (p1, p2) -> {
System.out.println("two parameters: " + p1 + ", " + p2);
return p1 + p2;
};
//lambda execute:
lambda5.apply(10, 20);
////////////////////////////////////////////
//6-three input(Integer,Integer,String) | by output(as Integer)
//lambda define:
ThreeParameterFunctionByReturn<Integer, Integer, Integer> lambda6 = (p1, p2, p3) -> {
System.out.println("three parameters: " + p1 + ", " + p2 + ", " + p3);
return p1 + p2 + p3;
};
//lambda execute:
lambda6.apply(10, 20, 30);
}
@FunctionalInterface
public interface TwoParameterFunctionWithoutReturn<T, U> {
public void apply(T t, U u);
}
@FunctionalInterface
public interface TwoParameterFunctionByReturn<T, U> {
public T apply(T t, U u);
}
@FunctionalInterface
public interface ThreeParameterFunctionByReturn<M, N, O> {
public Integer apply(M m, N n, O o);
}
}
在 Java 中,是否可以让 lambda 接受多种不同的类型?
即: 单变量有效:
Function <Integer, Integer> adder = i -> i + 1;
System.out.println (adder.apply (10));
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 })));
但我想要一些可以接受多种不同类型参数的东西,例如:
Function <String, Integer, Double, Person, String> myLambda = a , b, c, d-> {
[DO STUFF]
return "done stuff"
};
主要用途是为了方便在函数内部有小的内联函数。
我环顾了 google 并检查了 Java 的功能包,但没有找到。这可能吗?
如果您定义这样一个具有多个类型参数的功能接口,这是可能的。没有这样的内置类型。 (有一些具有多个参数的有限类型。)
@FunctionalInterface
interface Function6<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 {
Function6<String, Integer, Double, Void, List<Float>, Character> func = (a, b, c, d, e) -> 'z';
}
我在这里称它为Function6
。该名称由您自行决定,只是尽量不要与 Java 库中的现有名称冲突。
也没有办法定义可变数量的类型参数,如果这就是您要问的问题。
一些语言,如 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 "";
};
}}
另一种选择,不确定这是否适用于您的特定问题,但可能适用于某些问题,是在 java.util.function 库中使用 UnaryOperator
。
它 returns 与您指定的类型相同,因此您将所有变量放在一个 class 中并将其作为参数:
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;
}
}
所以您拥有的 class,在本例中 Person
,可以有许多实例变量,并且不必更改 lambda 表达式的参数。
对于那些感兴趣的人,我写了关于如何使用 java.util.function 库的笔记:http://sysdotoutdotprint.com/index.php/2017/04/28/java-util-function-library/
您也可以使用 jOOL 库 - https://github.com/jOOQ/jOOL
已经准备好不同参数个数的函数接口。例如,您可以使用 org.jooq.lambda.function.Function3
,等等,从 Function0
到 Function16
。
要使用 lambda :有三种类型的操作:
1. 接受参数 --> Consumer
2.测试参数return boolean --> Predicate
3. 操作参数和return值 --> Function
Java函数接口最多两个参数:
单参数接口
消费者
谓词
函数
双参数接口
双消费者
双谓词
双函数
如果超过两个,您必须创建功能接口如下(消费者类型):
@FunctionalInterface
public interface FiveParameterConsumer<T, U, V, W, X> {
public void accept(T t, U u, V v, W w, X x);
}
一些 lambda 函数:
import org.junit.Test;
import java.awt.event.ActionListener;
import java.util.function.Function;
public class TestLambda {
@Test
public void testLambda() {
System.out.println("test some lambda function");
////////////////////////////////////////////
//1-any input | any output:
//lambda define:
Runnable lambda1 = () -> System.out.println("no parameter");
//lambda execute:
lambda1.run();
////////////////////////////////////////////
//2-one input(as ActionEvent) | any output:
//lambda define:
ActionListener lambda2 = (p) -> System.out.println("One parameter as action");
//lambda execute:
lambda2.actionPerformed(null);
////////////////////////////////////////////
//3-one input | by output(as Integer):
//lambda define:
Function<String, Integer> lambda3 = (p1) -> {
System.out.println("one parameters: " + p1);
return 10;
};
//lambda execute:
lambda3.apply("test");
////////////////////////////////////////////
//4-two input | any output
//lambda define:
TwoParameterFunctionWithoutReturn<String, Integer> lambda4 = (p1, p2) -> {
System.out.println("two parameters: " + p1 + ", " + p2);
};
//lambda execute:
lambda4.apply("param1", 10);
////////////////////////////////////////////
//5-two input | by output(as Integer)
//lambda define:
TwoParameterFunctionByReturn<Integer, Integer> lambda5 = (p1, p2) -> {
System.out.println("two parameters: " + p1 + ", " + p2);
return p1 + p2;
};
//lambda execute:
lambda5.apply(10, 20);
////////////////////////////////////////////
//6-three input(Integer,Integer,String) | by output(as Integer)
//lambda define:
ThreeParameterFunctionByReturn<Integer, Integer, Integer> lambda6 = (p1, p2, p3) -> {
System.out.println("three parameters: " + p1 + ", " + p2 + ", " + p3);
return p1 + p2 + p3;
};
//lambda execute:
lambda6.apply(10, 20, 30);
}
@FunctionalInterface
public interface TwoParameterFunctionWithoutReturn<T, U> {
public void apply(T t, U u);
}
@FunctionalInterface
public interface TwoParameterFunctionByReturn<T, U> {
public T apply(T t, U u);
}
@FunctionalInterface
public interface ThreeParameterFunctionByReturn<M, N, O> {
public Integer apply(M m, N n, O o);
}
}