Java多个扫描器

我有一个类创建多个整数对象到链表上,如下所示:

public class Shares<E> implements Queue<E> {
protected LinkedList<E> L;


public Shares() {
    L = new LinkedList<E>();
}

public boolean add(E price) {
    System.out.println("How many of these shares would you like?");
    Scanner scanInt;
    scanInt = new Scanner(System.in);
    Integer noShares = scanInt.nextInt();
    for (int i = 0; i < noShares; i++) {
        L.addLast(price);
    }
    scanInt.close();

    return true;
}

我有一个应用程序从控制台扫描输入“添加”,如果发现调用方法add,如下所示:

public class Application {
private static Scanner scan;

public static <E> void main(String[] args) {
    Queue<Integer> S = new Shares<Integer>();
    scan = new Scanner(System.in);
    System.out.println("Please type add");
    String sentence = scan.nextLine();
    while (sentence.equals("quit") == false) {
        if (sentence.equals("add")) {

            System.out
                    .println("What price would you like to buy your shares at?");

            S.add((Integer) scan.nextInt());

        } else
            System.exit(0);

        sentence = scan.nextLine();
    }
}

}

应用程序应该允许用户按照他们的意愿多次输入“add”,但在调用add方法后出现“找不到行”的错误。

我猜这是因为该方法中的扫描仪尚未关闭,然后在需要时重新打开。 这是什么错误的程序,如果是的话,我将如何去解决它?

请注意,该程序尚未完成,因为我将添加销售这些股票的销售方法,这就是为什么我使用while循环的原因。


对于任何流有多个包装是一个真正混淆你自己的好方法。 我建议你除非真的知道自己在做什么,否则只能打包一次。

最简单的方法是在这种情况下使用单例,因为它包装了另一个单例(最好是将扫描器作为参数传递)

public class Application { 
    // use this Scanner in all you other code, don't create another one.
    static final Scanner scan = new Scanner(System.in);

    public static <E> void main(String[] args) {

我猜这是因为该方法中的扫描仪尚未关闭

一旦你关闭了一个流,它会关闭底层的流,你不能再使用它。 只有关闭System.in才能防止再次使用它。

我将如何去修复它?

最好的解决方案是让所有的扫描仪在一个地方,一个方法或一个类中使用。 你有你的main()完成与用户的所有交互并将值传递给你的数据结构。 拥有初始化自己的对象是一个不好的习惯,如果你开始这样做,它会困扰你的剩余的发展日子;)(严肃地说,你会看到这样做一次又一次,它往往是一场噩梦)


顺便说一句,不要没有解释地退出程序。 调用System.exit(0); 甚至没有错误信息也是一场噩梦。 我曾经在一个有260个调用System.exit()的项目上工作,而且经常没有错误信息,您可以想象诊断服务器有多么有趣,因为没有明显的原因。


第一个错误是这行代码

scanInt.close();

关闭System.in,而不仅仅是scanInt对象。 这意味着在第一次添加调用之后,扫描对象将只消耗它已有的输入,然后您将收到NoSuchElementException: 删除此行。

现在,如果你用这个替换最后一行

sentence = scan.nextLine();
System.out.println("sentence: "" + sentence + """);

你会看到你退出前的最后一个输入是一个空字符串。 因此在下一个循环中输入else语句,程序停止执行。 您可以通过添加以下内容来解决此问题:

scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value

但是,我会同意彼得,你不应该使用多个包装。 考虑将“扫描器”对象作为参数传递给Shares类承包商。


有多个扫描仪(在同一个流)是一个非常糟糕的做法,因为扫描仪消耗他们共享的流。

我已经验证了调试源代码并查看我发现的Scanner类:

  • 对源输入流的引用
  • 一个用于保存输入的内部专用缓冲区。
  • 所以当一个扫描程序实例使用它的流时,基本上它只是读取一堆字节(1024),并且流的位置向前移动。

    例如,当nextLine()方法是invoke时,在幕后source.read source.read()将结果复制到私有缓冲区中。

    显然其他扫描仪的状态会变坏(无效)。

    尝试自己调试Java源代码和/或查看Scanner.readInput()方法。

    链接地址: http://www.djcxy.com/p/96109.html

    上一篇: Java Multiple Scanners

    下一篇: Now am getting incompatible error when using the if else statements