我能够使用lambda的返回void并使用哈希表获取0 args,请参阅此处 - > Create lambda two dimensional array
现在,我正在尝试创建一个Runnable[]
数组,索引中包含lambda,每个lambda接受一个String参数并返回一个布尔值。
这是代码......
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)){
时,出现编译错误。知道为什么会这样吗?
答案 0 :(得分:1)
在Java语言中,Runnable
实例不能有参数,而具有参数的lambda则是Callable
个实例。换句话说,你的问题是不准确的......你不能创建带有参数的Runnable
数组,即使编译器(错误地)允许你这样做。
错误是Runnable
接口有一个带签名的run方法
public abstract void run()
然而,您正在尝试将参数传递给该run方法。
runnableNumArray[numChecked].run( num )
删除num
参数仍会出错。这是因为run方法返回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;
}
}
}
答案 1 :(得分:1)
这是因为Runnable
有方法void run()
,没有参数,而您正试图致电run(num)
。由于已num
参数已应用setNumFound()
,因此只需使用run()
进行调用。
当然,这会导致第二个错误,即方法返回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;
}
}
}