これを実行するときはいつでも、chooseCave()
関数はin.nextInt()
で正常に動作します。洞窟を選択すると、メッセージが2秒間隔でポップアップし、その部分を通過するとすぐにエラーが発生します。
_Exception in thread "main" Java.util.NoSuchElementException: No line found
at Java.util.Scanner.nextLine(Unknown Source)
at Dragon.main(Dragon.Java:81)
_
hasNextLine()
とhasNextInt()
を試してみましたが、main
メソッドでwhile hasNextLine()
を使用すると、さらに多くのエラーが発生します。 while hasNextInt()
メソッドでchooseCave()
を使用すると、入力を受け付けません。
if hasNextInt()
メソッドでchooseCave()
を使用すると、playAgain
文字列の入力が受け入れられず、別のゲームに直接進みますが、hasNextInt()
booleanはfalse
を返し、「Which cave ...」を無限にスパムします。
私はエラー報告とJava-docsとStack Overflowを同じような問題で経験しました。助けてください。
_import Java.util.Scanner;
public class Dragon {
public static void displayIntro() {
System.out.println("You are in a land full of dragons. In front of you, ");
System.out.println("You see two caves. In one cave, the dragon is friendly");
System.out.println("and will share his treasure with you. The other dragon");
System.out.println("is greedy and hungry, and will eat you on sight");
System.out.println(' ');
}
public static int chooseCave() {
Scanner in = new Scanner(System.in);
int cave = 0;
while (cave != 1 && cave != 2) {
System.out.println("Which cave will you go into? (1 or 2)");
cave = in.nextInt();
}
in.close();
return cave;
}
public static void checkCave(int chosenCave) {
System.out.println("You approach the cave...");
try
{
// Sleep at least n milliseconds.
// 1 millisecond = 1/1000 of a second.
Thread.sleep( 2000 );
}
catch ( InterruptedException e )
{
System.out.println( "awakened prematurely" );
}
System.out.println("It is dark and spooky...");
try
{
// Sleep at least n milliseconds.
// 1 millisecond = 1/1000 of a second.
Thread.sleep( 2000 );
}
catch ( InterruptedException e )
{
System.out.println( "awakened prematurely" );
}
System.out.println("A large dragon jumps out in front of you! He opens his jaws and...");
try
{
// Sleep at least n milliseconds.
// 1 millisecond = 1/1000 of a second.
Thread.sleep( 2000 );
}
catch ( InterruptedException e )
{
System.out.println( "awakened prematurely" );
}
double friendlyCave = Math.ceil(Math.random() * 2);
if (chosenCave == friendlyCave) {
System.out.println("Gives you his treasure!");
}
else {
System.out.println("Gobbles you down in one bite!");
}
}
public static void main(String[] args) {
Scanner inner = new Scanner(System.in);
String playAgain = "yes";
boolean play = true;
while (play) {
displayIntro();
int caveNumber = chooseCave();
checkCave(caveNumber);
System.out.println("Do you want to play again? (yes or no)");
playAgain = inner.nextLine();
if (playAgain == "yes") {
play = true;
}
else {
play = false;
}
}
inner.close();
}
}
_
基礎となるScanner
を閉じる2番目のInputStream
を閉じるため、最初のScanner
は同じInputStream
とNoSuchElementException
の結果から読み取ることができなくなります。
解決策:コンソールアプリの場合、単一のScanner
を使用して_System.in
_から読み取ります。
余談:すでに述べたように、_Scanner#nextInt
_は改行文字を消費しないことに注意してください。 Scanner#newLine()
を使用してnextLine
を再度呼び出す前に、これらが消費されていることを確認してください。
nextInt()
メソッドは_\n
_(行末)シンボルを残し、nextLine()
によってすぐに取得され、次の入力をスキップします。あなたがしたいことは、すべてに対してnextLine()
を使用し、後で解析することです:
_String nextIntString = keyboard.nextLine(); //get the number as a single line
int nextInt = Integer.parseInt(nextIntString); //convert the string to an int
_
これは、問題を回避する最も簡単な方法です。「次の」メソッドを混在させないでください。 nextLine()
のみを使用してから、int
sを解析するか、後で単語を区切ります。
また、入力にターミナルを1つだけ使用している場合は、Scanner
を1つだけ使用するようにしてください。それが例外のもう1つの理由である可能性があります。
最後の注意:_==
_演算子ではなく、String
を.equals()
関数と比較してください。
_if (playAgain == "yes"); // Causes problems
if (playAgain.equals("yes")); // Works every time
_
単に閉じないでください
コードからin.close()
を削除します。
in.closeがchooseCave()にあるため、Reimeusは正しいです。また、これは間違っています。
if (playAgain == "yes") {
play = true;
}
「==」の代わりに等号を使用する必要があります。
if (playAgain.equals("yes")) {
play = true;
}
誰もがそれについてかなりよく説明しました。このクラスをいつ使用するべきかについてお答えします。
NoSuchElementExceptionを使用すべき場合
Javaには、コレクション内の要素を反復処理するいくつかの異なる方法が含まれています。これらのクラスの最初のEnumerationは_JDK1.0
_で導入され、一般に非推奨と見なされ、IteratorやListIteratorなどの新しい反復クラスが優先されます。
ほとんどのプログラミング言語と同様に、Iteratorクラスには、反復に要素がもうあるかどうかを示すブール値を返すhasNext()
メソッドが含まれています。 hasNext()
がtrue
を返す場合、next()
メソッドは反復の次の要素を返します。 Enumerationとは異なり、Iteratorにはremove()
メソッドもあり、next()
を介して取得された最後の要素を削除します。
Iteratorは_Java Collections Framework
_のすべてのコレクションで使用するために一般化されていますが、ListIterator
はより専門的で、ArrayList
、LinkedList
などのリストベースのコレクションでのみ機能します。など。ただし、ListIterator
は、hasPrevious()
およびprevious()
メソッドを介して反復が両方向にトラバースできるようにすることで、さらに多くの機能を追加します。