Java多扫描仪
我有一个类,它创建多个Java多扫描仪,java,java.util.scanner,Java,Java.util.scanner,我有一个类,它创建多个Integer对象,并将它们放入LinkedList中,如下所示: public class Shares<E> implements Queue<E> { protected LinkedList<E> L; public Shares() { L = new LinkedList<E>(); } public boolean add(E price) {
Integer
对象,并将它们放入LinkedList
中,如下所示:
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;
}
}
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
方法后会出现错误“找不到行”
我猜这是因为方法中的扫描器
没有关闭,需要时再重新打开。这就是程序的问题所在吗?如果是,我将如何着手解决它
请注意,此程序尚未完成,因为我将添加一种出售这些股票的方法。这就是我使用while循环的原因。对于任何流都有多个包装器,这是一个很好的方法,可以让你自己感到困惑。我建议,除非你真的知道自己在做什么,否则你只需要包装一次 最简单的方法是在包装另一个单例时使用单例(最好是将扫描器作为参数传递)
公共类应用程序{
//在所有其他代码中使用此扫描仪,不要创建其他扫描仪。
静态最终扫描仪扫描=新扫描仪(System.in);
公共静态void main(字符串[]args){
我猜这是因为该方法中的扫描仪尚未关闭
关闭流后,它将关闭基础流,您无法再次使用它。如果要防止再次使用它,请仅关闭System.in
我该如何着手修理它
最好的解决方案是将所有扫描仪放在一个地方、一个方法或一个类中使用与用户进行所有交互,并将值传递给数据结构。让对象自己初始化是一种不好的做法,如果您开始这样做,它将在您的开发日的其余时间困扰您;)(说真的,您会一次又一次地看到这样做,这通常是一场噩梦)
顺便说一句,永远不要在没有解释的情况下退出一个程序。调用
System.exit(0);
甚至没有错误消息也是一场噩梦。我曾经参与过一个项目,该项目有260个对System.exit()的调用通常在没有错误消息的情况下,您可以想象诊断服务器只是无缘无故停止是多么有趣。第一个错误是这行代码
scanInt.close();
关闭System.in,而不仅仅是scanInt对象。这意味着在第一次调用add之后,scan对象将只使用它已经拥有的输入,然后您将收到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
<>但是,我同意彼得,你不应该使用多个包装器。考虑将扫描器对象作为共享类承包商中的一个参数传递。 拥有多个扫描器(在同一个流上)是一个非常糟糕的做法,因为扫描仪消耗它们共享的流。
我在调试扫描仪
类源代码时对其进行了验证,发现:
- 对源输入流的引用
- 用于保存输入的内部专用缓冲区
nextLine()
方法为invoket时,source.read()
会在后台将结果复制到专用缓冲区中
显然,其他扫描仪的状态已损坏(无效)
尝试自己调试Java源代码和/或查看方法。在S.add中调用scanner可能有问题吗?“…关闭System.in,而不仅仅是…”,这为我解决了另一个问题。谢谢。
scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value