Rya*_*son 12 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) {
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个应用程序从控制台扫描输入"添加",如果找到,调用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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
应用程序应允许用户根据需要多次输入"添加",但在add调用方法后出现错误"找不到行" .
我猜这是因为Scanner在方法中,尚未关闭,然后在需要时重新打开.这是程序出了什么问题,如果是这样,我该如何修复它?
请注意,此程序尚未完成,因为我将添加销售这些股票的销售方法.这就是我使用while循环的原因.
Pet*_*rey 13
拥有任何流的多个包装器是一个真正让自己迷惑的好方法.我建议你只有一次包裹一个流,除非你真的知道你在做什么.
最简单的方法是在这种情况下使用单例,因为它包装了另一个单例(最好是将Scanner作为参数传递)
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) {
Run Code Online (Sandbox Code Playgroud)
我猜这是因为该方法中的扫描仪尚未关闭
关闭流后,它会关闭基础流,您无法再次使用它.如果要阻止再次使用它,只关闭System.in.
我该怎么办呢?
最好的解决方案是让所有扫描仪在一个地方,一个方法或一个类中使用.您让main()完成与用户的所有交互,并将值传递给您的数据结构.拥有自我初始化的对象是一个不好的做法,如果你开始这样做,它将困扰你的余下的开发日;)(严重的是你会看到这一次又一次地完成,它往往是一场噩梦)
顺便说一下,如果没有解释,切勿退出程 System.exit(0);甚至没有错误消息的呼叫也是一场噩梦.我曾经做过一个项目,它有260个调用System.exit(),通常没有错误信息,你可以想象诊断一个服务器只是停止没有明显原因是多么有趣.
小智 6
第一个错误是这行代码
scanInt.close();
Run Code Online (Sandbox Code Playgroud)
关闭System.in,而不仅仅是scanInt对象.这意味着在第一次调用add之后,scan对象只会消耗它已有的输入,然后你会收到NoSuchElementException:删除这一行.
现在,如果你用这个替换你的最后一行
sentence = scan.nextLine();
System.out.println("sentence: \"" + sentence + "\"");
Run Code Online (Sandbox Code Playgroud)
你会看到退出前得到的最后一个输入是一个空字符串.因此,在下一个循环中输入else语句,程序将停止执行.您可以通过添加以下内容来解决此问题:
scan.nextLine(); // consume the first always empty String...
System.out.println("Please type add");
sentence = scan.nextLine(); // and then get the actual value
Run Code Online (Sandbox Code Playgroud)
但是,我同意彼得你不应该使用多个包装器.考虑将Scanner对象作为Shares类承包商中的参数传递.
拥有多个扫描仪(在同一个流上)是一种非常糟糕的做法,因为扫描仪会消耗它们共享的流。
\n我在调试类源代码时验证了它Scanner,并且我\xe2\x80\x99发现:
因此,当扫描器实例消耗其流时,基本上它只是读取一堆字节(1024)并且流的位置向前移动。
\n例如,当该nextLine()方法被调用时,在幕后source.read()结果复制到私有缓冲区中。
显然其他扫描仪的状态已损坏(无效)。
\n尝试自己调试 Java 源代码和/或查看方法Scanner.readInput()。
| 归档时间: |
|
| 查看次数: |
28970 次 |
| 最近记录: |