【问题标题】:Java, I dont understand why this is happening, variable changesJava,我不明白为什么会这样,变量更改
【发布时间】:2017-11-08 20:25:33
【问题描述】:
    public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");
    String enteredDate = in.nextLine();

    //This array will hold the 3 elements of which the date is made up of, day, month and year, and this method returns it.
    String[] dateEnteredSplit = enteredDate.split("/");

    //I am using the split method to seperate each number, which returns an array, so I am assigning that array to the dateEnteredSplit array.
    //dateEnteredSplit = enteredDate.split("/");
    //So now the first element holds the day, second the month, and the third element holds the year.

    //System.out.println(Arrays.toString(dateEnteredSplit));

    //Assigning each element and converting them to integers.
    int day = Integer.parseInt(dateEnteredSplit[0]);
    int month = Integer.parseInt(dateEnteredSplit[1]);
    int year = Integer.parseInt(dateEnteredSplit[2]);

    **System.out.println("day: " + day + "  month: " + month + "  year: " + year);**

    //The loop will be entered if any of the values are wrong. which will use recursion to call this method again for a chance to enter the date again.
    while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) {
        **System.out.println("day: " + day + "  month: " + month + "  year: " + year);**
        //Im calling these methods to inform which one specifially was wrong so they know what they need to change.
        this.setDay(day);
        this.setMonth(month);
        this.setYear(year);

        dateEnteredSplit[0] = "0";
        askForDate(in);
    }

    //I then assign any correct value into the object attribute because the while loop is either finished or not entered at all. 
    //No need to use setDay etc. here because the checks have been done above in the while loop.
    this.day = day;
    this.month = month;
    this.year = year;  
}

好的,这是一个类中的方法。它要求输入格式为 dd/mm/yyyy

如果我第一次输入 1996 年 12 月 1 日,它可以工作,但如果我首先输入错误的日期,例如 123/123/123,然后输入正确的日期,例如 1996 年 12 月 1 日,它仍然进入循环。

调试后,第一行加粗的值与第二行加粗的值不同,好像值是自己变化的。

这里有什么问题?过去 1 小时内我一​​直在尝试找出答案。

提前致谢!

【问题讨论】:

  • 看起来这是因为递归。一旦他们输入正确的值,您的函数就会结束调用,然后一旦您返回上一个方法,就会分配旧值。一种肮脏的方法是,将正确的值返回给先前的函数调用
  • 不要使用递归处理无效输入,而是使用循环(请求输入直到输入有效)。使用递归只会产生问题和混淆代码。

标签: java variables random methods


【解决方案1】:

问题很可能在于您尝试结合递归和迭代方法来更新值的方式(有一个while循环,递归调用函数,这也可能在下一级调用和上一级触发while循环一个人会继续递归地调用自己,你最终只会一团糟)

没有真正的理由递归地这样做,我只会使用迭代方法,如下所示:

public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");

    int day, month, year;
    do { // We use do-while to get the first read without condition, although setting date to invalid value (like day = 0) and then running standard while loop will work just as fine
        String[] dateEnteredSplit = in.nextLine().split("/");

        //Assigning each element and converting them to integers.
        day = Integer.parseInt(dateEnteredSplit[0]);
        month = Integer.parseInt(dateEnteredSplit[1]);
        year = Integer.parseInt(dateEnteredSplit[2]);
    } while (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000));

    // Now day month and year variables are set correctly and we can do stuff with it
}

如果你坚持或递归的方法,正确的方法是只调用一次函数:

public void askForDate(Scanner in) {
    System.out.println("Please enter the date that the vehicle entered the car park in this format dd/mm/yyyy :");

    int day, month, year;
    String[] dateEnteredSplit = in.nextLine().split("/");

    //Assigning each element and converting them to integers.
    day = Integer.parseInt(dateEnteredSplit[0]);
    month = Integer.parseInt(dateEnteredSplit[1]);
    year = Integer.parseInt(dateEnteredSplit[2]);

    if (!(day >= 1 && day <= 31) || !(month >= 1 && month <= 12) || !(year > 1000 && year < 5000)) askForDate(in);

    // You need to save day/month/year variables to other than local scope (like this.day = day)
    // Otherwise it would just somewhere in recursion stack and you wouldn't be able to use it
}

为了完整起见,请记住,日期字符串可能以其他方式出错,只是数字超出范围。如果用户输入 1. 2. 3456a/b/c 或者甚至没有像 Hello 这样非常不同的东西怎么办? 在您的 sn-p 代码会崩溃(尝试解析非整数时抛出 NumberFormatException 或在不存在的元素处访问 dateEnteredSplit 数组时抛出 ArrayIndexOutOfBoundsException (“Hello”中没有“/”))

【讨论】:

  • 约翰....你很棒。我只是无缘无故地把它复杂化了。我在Java编程方面有5个月的空白,我根本没有编程,当时我想我会得到它,但是现在我失去了一些基本技术,因为这个巨大的空白。关于如何重回正轨的任何建议?我是二年级软件工程师学生。
  • 好吧,如果你想在某件事上做得更好(比如编程),那就去做那件事,尝试越来越难的问题并通过这种方式获得经验。如果您对算法问题感兴趣,请尝试projecteuler 或任何其他类似的东西。
【解决方案2】:

这就是发生的事情。第一次 while 循环迭代中的错误值使调用 askForDate 成为可能。您会收到第二个提示并提供正确的输入。 askForDate 的第二次调用按预期结束。执行再次返回到 while 循环,您仍然有第一个错误设置的值,并且该过程再次开始。

如果你真的想在这里使用递归,你应该从你的函数中返回一个值(日期或布尔标志)并在 while 循环条件中检查它。

【讨论】:

    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    相关资源
    最近更新 更多