web-dev-qa-db-ja.com

スレッド「メイン」の例外Java.util.NoSuchElementException

これを実行するときはいつでも、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();

}

}
_
8
Isaac Smith

基礎となるScannerを閉じる2番目のInputStreamを閉じるため、最初のScannerは同じInputStreamNoSuchElementExceptionの結果から読み取ることができなくなります。

解決策:コンソールアプリの場合、単一のScannerを使用して_System.in_から読み取ります。

余談:すでに述べたように、_Scanner#nextInt_は改行文字を消費しないことに注意してください。 Scanner#newLine()を使用してnextLineを再度呼び出す前に、これらが消費されていることを確認してください。

参照: 単一のInputStreamに複数のバッファー付きラッパーを作成しないでください

12
Reimeus

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()のみを使用してから、intsを解析するか、後で単語を区切ります。


また、入力にターミナルを1つだけ使用している場合は、Scannerを1つだけ使用するようにしてください。それが例外のもう1つの理由である可能性があります。


最後の注意:_==_演算子ではなく、String.equals()関数と比較してください。

_if (playAgain == "yes"); // Causes problems
if (playAgain.equals("yes")); // Works every time
_
6
syb0rg

単に閉じないでください

コードからin.close()を削除します。

2
Abhishek Goel

in.closechooseCave()にあるため、Reimeusは正しいです。また、これは間違っています。

if (playAgain == "yes") {
      play = true;
}

「==」の代わりに等号を使用する必要があります。

if (playAgain.equals("yes")) {
      play = true;
}
1
cwhsu

誰もがそれについてかなりよく説明しました。このクラスをいつ使用するべきかについてお答えします。

NoSuchElementExceptionを使用すべき場合

Javaには、コレクション内の要素を反復処理するいくつかの異なる方法が含まれています。これらのクラスの最初のEnumerationは_JDK1.0_で導入され、一般に非推奨と見なされ、IteratorやListIteratorなどの新しい反復クラスが優先されます。

ほとんどのプログラミング言語と同様に、Iteratorクラスには、反復に要素がもうあるかどうかを示すブール値を返すhasNext()メソッドが含まれています。 hasNext()trueを返す場合、next()メソッドは反復の次の要素を返します。 Enumerationとは異なり、Iteratorにはremove()メソッドもあり、next()を介して取得された最後の要素を削除します。

Iteratorは_Java Collections Framework_のすべてのコレクションで使用するために一般化されていますが、ListIteratorはより専門的で、ArrayListLinkedListなどのリストベースのコレクションでのみ機能します。など。ただし、ListIteratorは、hasPrevious()およびprevious()メソッドを介して反復が両方向にトラバースできるようにすることで、さらに多くの機能を追加します。

0