Java方法似乎跳过了第二次调用的步骤

时间:2018-07-03 07:40:43

标签: java user-input

我正在用Java编写一个简单的“购物篮”程序,在过去10年中根本没有使用它,我只是想再次熟悉它...

我的程序当前有3个类:Program.javaBasket.javaItem.java

Program.java定义为:

public class Program {

    public static int menuSelection = 0;
    public static Scanner kb = new Scanner(System.in);
    public static Basket basket = new Basket();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //Program p = new Program();
        menu();
    }

    public static void menu() {
        System.out.println("Press 1 to add an item to the basket. ");
        System.out.println("Press 2 to remove an item from the basket. ");
        System.out.println("Press 3 to display the basket contents. ");
        System.out.println("Press 9 to proceed to checkout. ");
        System.out.println("Press 0 to exit program");
        menuSelection = kb.nextInt();

        if(menuSelection == 1) {
            basket.addItemToBasket();
        } else if(menuSelection == 2) {
            basket.removeItemFromBasket();
        } else if (menuSelection == 3) {
            basket.displayBasket();
        } else if(menuSelection == 9) {
            System.out.println("Proceed to checkout");
        } else if(menuSelection == 0) {
            System.exit(0);
        }
    }

}

Basket.java定义为:

public class Basket {

    public ArrayList<Item> basket = new ArrayList<Item>();
    public Scanner kb = new Scanner(System.in);
    public Item item = new Item();
    public Program prog = new Program();

    public void addItemToBasket() {
        System.out.println("Enter the name of the item: ");
        item.name = kb.nextLine();
        System.out.println("Enter the price of the item: ");
        item.price = kb.nextDouble();
        basket.add(item);
        item.name = null;
        item.price = 0;
        Program.menu();
    }

    public void removeItemFromBasket() {
        System.out.println("Which item would you like to remove? ");
        item.name = kb.nextLine();
        if(basket.contains(item.name) ) {
            basket.remove(item);
        } else {
            System.out.printf("There is no %s currently in the basket! ", item.name);
        }
    }

    public String displayBasket() {
        return basket.toString();
    }



}

此刻,如果我运行该程序,则控制台中会显示菜单,并且当我选择“ 1”时,将调用addItemToBasket()方法,我会在第一个提示处输入名称,并在第二个提示,然后再次显示菜单。

但是,在这一点上,如果我再次选择“ 1”以将另一个项目添加到购物篮中,则第一和第二个提示会一起显示...即,而不是:

  

输入商品名称:

     

//等待用户输入

     

输入商品价格:

     

//等待用户输入

它显示:

  

输入商品名称:

     

输入商品价格:

如果我尝试键入数字以外的任何内容,则程序会崩溃,因为它期望使用双精度值...

我在做什么错?为什么addItemToBasket()方法在第二次及其后的调用中跳过item.name = kb.nextLine();行?

2 个答案:

答案 0 :(得分:4)

我以前从我的一个学生那里看到过这个。问题是您要从同一输入创建两个不同的扫描仪。这意味着每个扫描仪都在读取同一组输入。尝试绕过一台扫描仪进行读取,我敢打赌您的程序将再次开始运行。

这是更详细的说明。程序将创建名为kb的扫描程序,并读取您为其输入1的下一个整数。然后Basket的kb实例读取整行。感觉好像它跳过了该读取,但实际上是从流的开始读取它的。如果您打印item.name,您会看到一个1。现在它要价。您输入的数字很好,然后返回到主菜单。但是,最后一次读取1的主菜单仍然具有您输入的所有其他输入,以便读取篮。这就是为什么它对期望加倍并接收无效字符感到生气。

答案 1 :(得分:0)

作为@Spidy固定点,它与您的输入流有关。来看一下,2个扫描仪共享相同的输入流:

new Scanner(System.in);

因此,当您执行nextLine()时,期望输入新行。快速修复将代替nextLine(),仅使用next()。

P / S:检查@azro的注释,您在Basket类中有未使用的代码。