Как возврат значения работает в рекурсивном методе?[Джава] - PullRequest
0 голосов
/ 16 мая 2018

TLDR: Кажется, что Java возвращает первое значение только при запуске метода.Я ошибаюсь в этом, или есть обходной путь, о котором я не знаю [не прибегая к циклам] ?

Моя цель - вывести последнее значение [логическое] из возвращаемого значения, которому присваиваетсяк методу, однако я не могу сделать это без должного понимания того, как работает return.


Цель кода - вернуть логическое значение из простого выбора [Y / N] путем чтенияпользовательский ввод.Если указан неправильный вывод [например: «p», «P», «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;
}

Но лично я предпочитаю не делать этого, если я полностью не знаю, что нет другого решения или нет явной ошибки в моем коде.[Также хочу расширить этот код, чтобы он стал немного более универсальным.]

В конечном счете, я хочу иметь возможность понять, какую ошибку я допустил или, если ее нет, ограничения возвратав этом случае, даже если это означает, что я должен отказаться от своего кода для цикла do-while.

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Я не думаю, что вам здесь даже нужна рекурсия, и похоже, что вы понимаете, для чего она используется неправильно.Ваша третья попытка с циклом 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;
}
0 голосов
/ 16 мая 2018

Просто внесите небольшое изменение в ваш метод, как указано ниже

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;
}
0 голосов
/ 16 мая 2018

Вы должны вернуть значение, возвращаемое рекурсивным вызовом:

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.

...