初始化 Lambdas 的可运行数组(使用字符串 arg 和 returns 布尔值)和调用索引
Initialize Runnable Array of Lambdas(with string arg and returns a boolean) and Call Index
我能够使用 lambda 返回的 void 并使用哈希 table 接收 0 个参数,请参阅此处 ->
现在,我正在尝试创建一个 Runnable[]
数组,在索引中包含 lambda,每个 lambda 接受一个字符串参数和 returns 一个布尔值。
这是代码...
public class testLambdaWithPrimitiveType {
private final String[] numArray = {"One", "Two", "Three"};
private boolean numFound = false;
testLambdaWithPrimitiveType(String num){
setNumFound(num);
}
private void setNumFound(String num){
Runnable[] runnableNumArray = {
() -> isStringOne(num),
() -> isStringTwo(num),
() -> isStringThree(num)
};
for (int numChecked = 0; numChecked < runnableNumArray.length; numChecked++){
if (runnableNumArray[numChecked].run(num)){
this.numFound = true;
}
}
}
private boolean isNumFound(){return this.numFound;}
private boolean isStringOne(String num){
return num.equals(numArray[0]);
}
private boolean isStringTwo(String num){
return num.equals(numArray[1]);
}
private boolean isStringThree(String num){
return num.equals(numArray[2]);
}
public static void main(String[] args) {
testLambdaWithPrimitiveType objectOne = new testLambdaWithPrimitiveType("One");
testLambdaWithPrimitiveType objectTwo = new testLambdaWithPrimitiveType("Two");
testLambdaWithPrimitiveType objectThree = new testLambdaWithPrimitiveType("Three");
testLambdaWithPrimitiveType objectFour = new testLambdaWithPrimitiveType("Four");
System.out.println(objectFour.isNumFound()); // false
System.out.println(objectThree.isNumFound()); // true
System.out.println(objectTwo.isNumFound()); // true
System.out.println(objectOne.isNumFound()); // true
}
}
看起来数组已正确初始化,但当我尝试调用索引 if (runnableNumArray[numChecked].run(num)){
时,出现编译错误。知道为什么会这样吗?
在Java语言中,Runnable
个实例不能有参数,有参数的lambda是Callable
个实例。换句话说,你的问题是不准确的......你不能创建 Runnable
带参数的数组,即使编译器(错误地)允许你这样做。
错误是Runnable
接口有一个带有签名的运行方法,
public abstract void run()
但您正在尝试将参数传递给 运行 方法。
runnableNumArray[numChecked].run( num )
去掉num
参数还是会报错。这是因为 运行 方法 returns void
是 nothing (再次查看签名)但是 if
语句需要 boolean
要评估的值。
我不确定你想用这个 lambda 数组实现什么。如果您给我更多信息,我也许可以更正您的代码。但就目前而言,尚不清楚您期望 Runnables
实现什么。
这是一个使用 Callable 实例实现您想要的东西的示例。
private void setNumFound(String num) throws Exception {
Callable[] runnableNumArray = {
() -> isStringOne( num ),
() -> isStringTwo( num ),
() -> isStringThree( num )
};
for ( int numChecked = 0; numChecked < runnableNumArray.length; numChecked++ ){
if ( ( Boolean ) runnableNumArray[numChecked].call() ){
this.numFound = true;
}
}
}
那是因为 Runnable
has method void run()
,没有参数,而您正在尝试调用 run(num)
。由于 num
已经从 setNumFound()
参数应用,只需使用 run()
.
调用
当然,这会导致第二个错误,即方法 returns void
,因此 if (run())
不起作用。
您似乎需要一个方法 boolean xxx(String)
,因此将 Runnable
替换为 Predicate<String>
,您可以使用 test(num)
而不是 run()
来调用它。
这会导致编译错误 Cannot create a generic array of Predicate<String>
,因此您必须将数组替换为 List
。
然后您可以改用方法引用。
private void setNumFound(String num){
List<Predicate<String>> runnableNumList = Arrays.asList(
this::isStringOne,
this::isStringTwo,
this::isStringThree
);
for (Predicate<String> runnableNum : runnableNumList){
if (runnableNum.test(num)){
this.numFound = true;
}
}
}
private void setNumFound(String num){
boolean[] a = new boolean[1];
Runnable[] runnableNumArray = {
() -> a[0] = isStringOne(num),
() -> a[0] = isStringTwo(num),
() -> a[0] = isStringThree(num)
};
for (Runnable r : runnableNumArray ) {
r.run();
if ( a[0] ) {
this.numFound = true;
break; }
}
}
我重写了您的方法并将布尔变量添加为数组[1]。我认为,写错了,在一般情况下你会得到错误:"local variables referenced from a lambda expression must be final or effectively final" - 但它在 Java SE 8(build 31)中工作。
我能够使用 lambda 返回的 void 并使用哈希 table 接收 0 个参数,请参阅此处 ->
现在,我正在尝试创建一个 Runnable[]
数组,在索引中包含 lambda,每个 lambda 接受一个字符串参数和 returns 一个布尔值。
这是代码...
public class testLambdaWithPrimitiveType {
private final String[] numArray = {"One", "Two", "Three"};
private boolean numFound = false;
testLambdaWithPrimitiveType(String num){
setNumFound(num);
}
private void setNumFound(String num){
Runnable[] runnableNumArray = {
() -> isStringOne(num),
() -> isStringTwo(num),
() -> isStringThree(num)
};
for (int numChecked = 0; numChecked < runnableNumArray.length; numChecked++){
if (runnableNumArray[numChecked].run(num)){
this.numFound = true;
}
}
}
private boolean isNumFound(){return this.numFound;}
private boolean isStringOne(String num){
return num.equals(numArray[0]);
}
private boolean isStringTwo(String num){
return num.equals(numArray[1]);
}
private boolean isStringThree(String num){
return num.equals(numArray[2]);
}
public static void main(String[] args) {
testLambdaWithPrimitiveType objectOne = new testLambdaWithPrimitiveType("One");
testLambdaWithPrimitiveType objectTwo = new testLambdaWithPrimitiveType("Two");
testLambdaWithPrimitiveType objectThree = new testLambdaWithPrimitiveType("Three");
testLambdaWithPrimitiveType objectFour = new testLambdaWithPrimitiveType("Four");
System.out.println(objectFour.isNumFound()); // false
System.out.println(objectThree.isNumFound()); // true
System.out.println(objectTwo.isNumFound()); // true
System.out.println(objectOne.isNumFound()); // true
}
}
看起来数组已正确初始化,但当我尝试调用索引 if (runnableNumArray[numChecked].run(num)){
时,出现编译错误。知道为什么会这样吗?
在Java语言中,Runnable
个实例不能有参数,有参数的lambda是Callable
个实例。换句话说,你的问题是不准确的......你不能创建 Runnable
带参数的数组,即使编译器(错误地)允许你这样做。
错误是Runnable
接口有一个带有签名的运行方法,
public abstract void run()
但您正在尝试将参数传递给 运行 方法。
runnableNumArray[numChecked].run( num )
去掉num
参数还是会报错。这是因为 运行 方法 returns void
是 nothing (再次查看签名)但是 if
语句需要 boolean
要评估的值。
我不确定你想用这个 lambda 数组实现什么。如果您给我更多信息,我也许可以更正您的代码。但就目前而言,尚不清楚您期望 Runnables
实现什么。
这是一个使用 Callable 实例实现您想要的东西的示例。
private void setNumFound(String num) throws Exception {
Callable[] runnableNumArray = {
() -> isStringOne( num ),
() -> isStringTwo( num ),
() -> isStringThree( num )
};
for ( int numChecked = 0; numChecked < runnableNumArray.length; numChecked++ ){
if ( ( Boolean ) runnableNumArray[numChecked].call() ){
this.numFound = true;
}
}
}
那是因为 Runnable
has method void run()
,没有参数,而您正在尝试调用 run(num)
。由于 num
已经从 setNumFound()
参数应用,只需使用 run()
.
当然,这会导致第二个错误,即方法 returns void
,因此 if (run())
不起作用。
您似乎需要一个方法 boolean xxx(String)
,因此将 Runnable
替换为 Predicate<String>
,您可以使用 test(num)
而不是 run()
来调用它。
这会导致编译错误 Cannot create a generic array of Predicate<String>
,因此您必须将数组替换为 List
。
然后您可以改用方法引用。
private void setNumFound(String num){
List<Predicate<String>> runnableNumList = Arrays.asList(
this::isStringOne,
this::isStringTwo,
this::isStringThree
);
for (Predicate<String> runnableNum : runnableNumList){
if (runnableNum.test(num)){
this.numFound = true;
}
}
}
private void setNumFound(String num){
boolean[] a = new boolean[1];
Runnable[] runnableNumArray = {
() -> a[0] = isStringOne(num),
() -> a[0] = isStringTwo(num),
() -> a[0] = isStringThree(num)
};
for (Runnable r : runnableNumArray ) {
r.run();
if ( a[0] ) {
this.numFound = true;
break; }
}
}
我重写了您的方法并将布尔变量添加为数组[1]。我认为,写错了,在一般情况下你会得到错误:"local variables referenced from a lambda expression must be final or effectively final" - 但它在 Java SE 8(build 31)中工作。