返回值如何在递归方法中起作用? [爪哇]

时间:2018-05-16 10:41:51

标签: java recursion switch-statement return-value boolean-expression

TLDR: java似乎只在运行方法时返回第一个值。我错了吗,还是有一种解决方法我不知道[不求助于循环]

我的目标是输出分配给方法的返回值的最后一个值[boolean],但是如果没有正确理解返回的工作原理我就无法做到。

代码的目的是通过读取用户输入从简单的选择[Y / N]返回布尔值。如果给出了错误的输出[例如:" p"," P",#34; apple"],该方法应该再次提示用户,直到正确的输入是给出。

这是我刚开始的时候:

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" :              isNewRelease = true;  break;
        case "N" : case "n" :              isNewRelease = false; break;
        default  : /*Try again*/ nrCheck();                      break; 
    }

    return isNewRelease;
}

显然这不起作用,因为默认情况下没有分配值, 导致初始化错误。

尝试通过分配默认值来解决此问题,如下所示:

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" :        isNewRelease = true;            break;
        case "N" : case "n" :        isNewRelease = false;           break;
        default  : /*printTryagain*/ isNewRelease = null;  nrCheck();break; 
    }

    return isNewRelease;
}

这提出了一个新问题。出于某种原因,当我再次回忆该方法时,已经设置了返回值。我试图玩代码的顺序,但它并没有真正做多少。我的推测是,一旦你回想起这个方法,就会自动设置返回值,如果第一次设置你就不能改变它。

而且我知道我可以做到这一点,

private Boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);
    Boolean isNewRelease;


    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    do 
    {
        switch (movieType)
        {
            case "Y" : case "y" :        isNewRelease = true;            break;
            case "N" : case "n" :        isNewRelease = false;           break;
            default  : /*printTryagain*/ isNewRelease = null;  nrCheck();break; 
        }
    }
    while (movieType.equalsIgnoreCase("Y") || movieType.equalsIgnoreCase("N"))

    return isNewRelease;
}

但我个人不愿意,除非我完全清楚没有其他解决方案,否则我的代码中没有明显的错误。 [也想扩展这段代码,使其变得更加通用]。

最终,我希望能够理解我所犯的错误,或者在这种情况下是否存在任何错误,即使这意味着我必须废弃我的代码 - while循环。

3 个答案:

答案 0 :(得分:6)

您应该返回递归调用返回的值:

private boolean nrCheck()
{   
    Scanner sc = new Scanner (System.in);

    System.out.println("New Release [Y/N]? ");      
    String movieType = sc.nextLine();       

    switch (movieType)
    {
        case "Y" : case "y" : return true;
        case "N" : case "n" : return false;
        default  : return nrCheck();
    }
}

如果忽略该值,那么首先进行递归调用是没有意义的。

P.S。,您可以将方法的返回类型更改为boolean,因为它永远不会返回null

答案 1 :(得分:1)

我认为你甚至不需要在这里递归,看起来你正在理解错误地使用了什么。使用do循环进行的第三次尝试是轮询用户输入的典型方式:

private boolean nrCheck() {
    Scanner sc = new Scanner (System.in);
    boolean isNewRelease;

    System.out.println("New Release [Y/N]? ");      
    menuRedirect(movieType);    // don't know what this is doing...

    do {
        String movieType = sc.nextLine();
    } while (!movieType.equalsIgnoreCase("Y") && !movieType.equalsIgnoreCase("N"));

    // at this point, the movie type can only be y/Y/n/N
    isNewRelease = movieType.equalsIgnoreCase("Y") ? true : false;

    return isNewRelease;
}

答案 2 :(得分:1)

只需在您的方法中进行小改动,如下所示

private Boolean nrCheck() {

    Scanner sc = new Scanner(System.in);
    Boolean isNewRelease = null;


    //While loop here which break only if isNewRelease value is 
    //Non null(true or false)
    while (isNewRelease == null) {

        System.out.println("New Release [Y/N]? ");
        String movieType = sc.nextLine();

        menuRedirect(movieType);

        switch (movieType) {
            case "Y":
            case "y":
                isNewRelease = true;
                break;
            case "N":
            case "n":
                isNewRelease = false;
                break;
            default:
                System.out.println("Try Again");
                /*I removed recursive call which not required because recursive calls always creates new stack frames so it is recommenced that if we are going to use such calls we need to go with tail recursion.*/    
                isNewRelease = null;
                break;
        }

    }

    return isNewRelease;
}