Java 初始化lambda的可运行数组(使用字符串arg并返回布尔值)和调用索引

Java 初始化lambda的可运行数组(使用字符串arg并返回布尔值)和调用索引,java,arrays,lambda,runnable,Java,Arrays,Lambda,Runnable,我能够使用lambda的返回void并使用哈希表获取0个arg,请参见这里-> 现在,我正在尝试创建一个Runnable[]数组,索引中有lambda,每个lambda接受一个字符串参数并返回一个布尔值 这是代码 public class testLambdaWithPrimitiveType { private final String[] numArray = {"One", "Two", "Three"}; private boolean numFound = false;

我能够使用lambda的返回void并使用哈希表获取0个arg,请参见这里->

现在,我正在尝试创建一个
Runnable[]
数组,索引中有lambda,每个lambda接受一个字符串参数并返回一个布尔值

这是代码

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
    }
}
公共类testLambdaWithPrimitiveType{
私有最终字符串[]numArray={“一”、“二”、“三”};
私有布尔numFound=false;
testLambdaWithPrimitiveType(字符串编号){
setNumFound(num);
}
私有void setNumFound(字符串num){
Runnable[]runnableNumArray={
()->isStringOne(num),
()->isStringTwo(num),
()->isStringThree(num)
};
对于(int numChecked=0;numChecked

看起来数组初始化正确,但是当我尝试调用索引
if(runnableNumArray[numChecked].run(num))时{
,我得到了一个编译错误。知道为什么会发生这种情况吗?

在Java语言中,
可运行的
实例不能有参数,有参数的lambda是可调用的
实例。换句话说,你的问题是不准确的……你不能创建接受参数的
可运行的
数组,即使尽管编译器(错误地)允许您这样做

错误是
Runnable
接口有一个带有签名的run方法

public abstract void run()

然而,您正在尝试向该run方法传递一个参数

runnableNumArray[numChecked]。运行(num)

删除
num
参数仍然会给您一个错误。这是因为run方法返回
void
,这不是什么(再次查看签名),但是
如果
语句需要一个
布尔值来计算,则返回

我不确定你想用这个lambda数组实现什么。如果你给我更多的信息,我可能能够更正你的代码。但是,目前还不清楚你希望
可运行文件
实现什么

下面是一个使用可调用实例实现所需内容的示例

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;
    }
  }
}
private void setNumFound(String num)引发异常{
可调用[]runnableNumArray={
()->isStringOne(num),
()->isStringTwo(num),
()->isStringThree(num)
};
对于(int numChecked=0;numChecked
这是因为has方法没有参数,您正试图调用
run(num)
。由于
num
已经从
setNumFound()
参数中应用,只需使用
run()
调用即可

当然,这会导致第二个错误,即方法返回
void
,因此
if(run())
不起作用

似乎您可能需要一个方法
boolean xxx(String)
,因此将
Runnable
替换为,您可以使用
test(num)
而不是
run()
调用它

这将导致编译错误
无法创建谓词的泛型数组,因此必须使用

然后可以使用方法引用

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){
List runnableNumList=Arrays.asList(
这件事已经过去了,
这个:isStringTwo,
这是三个
);
for(谓词runnableNum:runnableNumList){
if(runnableNum.test(num)){
this.numFound=true;
}
}
}

我重写了您的方法,并将布尔变量添加为数组[1]。我认为,写错了,在一般情况下,您会得到错误:“从lambda表达式引用的局部变量必须是final或有效final”-但它在Java SE 8(build 31)中的工作.

我试图避免使用一长串
if/else if
语句。在我的实际应用程序中,我想如果我可以设置两个大小相同的
Runnable[]
数组,并在if条件下使用第一个数组返回bool(基本上就是这个问题),则可以使用索引执行第二个数组[lambda]。听起来我可能必须编写一个新类,用Runnable对象覆盖
run()
(除非Runnable有一个方法支持返回基元类型的函数run())@FiddleFreak lambda已经覆盖了
Runnable
接口。我认为Runnable的使用是你遇到麻烦的地方。你能解释一下你试图通过输入和输出细节来实现什么,而不是你正在使用的类的细节吗?我在这里
    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; }
    }
}