質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.55%

Java indexOfのエラー

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 797

snmn16

score 6

前提・実現したいこと

入力された1から10までの数字をリストから削除するコードを書いています。
1から10まで以外の数字が入力された場合と、一度入力された数字と同じ数字が入力された場合に『その数字は選べないよ!』と出力したいのですが、うまく行きません。
下記に記述してますが、エラーの場所は分かっていても何をどうすればいいかがわかっていない状況です。ご教授お願い致します。

発生している問題・エラーメッセージ

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at java.util.ArrayList.elementData(ArrayList.java:422)
    at java.util.ArrayList.remove(ArrayList.java:499)
    at kurohige.Kurohige.main(Kurohige.java:30)

該当のソースコード

package kurohige;

import java.util.ArrayList;
import java.util.Scanner;

    public class Kurohige {

    public static void main(String[] args) throws Exception {

        System.out.println("【黒ひげ危機一髪ゲーム!】");
        System.out.println("下記から好きな数字を入力してください。");
        System.out.println("[1,2,3,4,5,6,7,8,9,10]");
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        ArrayList<Integer> array = new ArrayList<>();

        array.add(1);
        array.add(2);
        array.add(3);
        array.add(4);
        array.add(5);
        array.add(6);
        array.add(7);
        array.add(8);
        array.add(9);
        array.add(10);

        while (n != 4){
            array.remove(array.indexOf(n));
            System.out.println("セーフ!");
            System.out.println("");
            System.out.println("下記から好きな数字を入力してください。");
            System.out.println(array);
            n = scan.nextInt();

        }if(n == -1) {

        System.out.println("その数字は選べないよ!");
        System.out.println("下記から好きな数字を入力してください。");

        n = scan.nextInt();

        }else if(n == 4)
        {
        System.out.println("【ドッカーン!!】");

  }

}


    }

試したこと

スタックトレースを見るに、30行目のindexOfの部分が何か間違ってるのだろうとはわかるのですが、具体的にどうすればいいかがわかりません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

checkベストアンサー

+1

array.indexOf(n) は、n が array 内に存在しないときに -1 を返します。
-1は、有効なindex(0〜(array.size()-1))ではないでの、java.lang.ArrayIndexOutOfBoundsExceptionが発生します。
そのため、array.removeの前に、array.indexOf(n) == -1の場合の処理が必要です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/04/11 17:18

    なるほど、確かに先にそちらを処理しないと何を書いても例外が発生してしまいますね。
    アドバイスありがとうございます、処理を記述してみます。

    キャンセル

+1

30行目というのは array.remove(array.indexOf(n)); でしょうか?

ここに書かれているメソッドで ArrayIndexOutOfBoundsException を発生させるのは, indexOf ではなく, remove のほうです.
array.remove(-1); となって例外が発生していますので, array.indexOf(n) が -1 を返していることになります.
indexOf が -1 を返すのは

indexOf

public int indexOf(Object o)
指定された要素がこのリスト内で最初に検出された位置のインデックスを返します。指定された要素がこのリストにない場合は -1を返します。つまり、(o==null ? get(i)==null : o.equals(get(i)))となる、最小のインデックスiを返します。そのようなインデックスが存在しない場合は -1を返します。
定義:
indexOf、インタフェース: List<E>
オーバーライド:
indexOf、クラス: AbstractList<E>
パラメータ:
o - 検索する要素
戻り値:
指定された要素がリスト内で最初に検出された位置のインデックス。その要素がリストにない場合は -1

n が array に無い場合です.

while 文の中に n が array に無い場合の処理が有りませんので, この状況となっているものと思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

「java.lang.ArrayIndexOutOfBoundsException」の意味は調べてみましたか?

また、「n」「array.indexOf(n) の戻り値」の値を System.out.println() やデバッガで確認してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

まあネタの実装例(一部無駄処理があるはず)

package example.v01;

import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

    public static void main(String[] args) {

        List<Integer> numberList = IntStream.range(1, 10).mapToObj(Integer::valueOf)
                .collect(Collectors.toList());
        List<Integer> numberListOrg = numberList.stream().collect(Collectors.toList());

        try (Scanner in = new Scanner(System.in)) {
            while (!numberList.isEmpty()) {
                System.out.printf("数値を入力してください。 %s : ", numberList.toString());
                String line = "";
                try {
                    if (in.hasNext()) {
                        line = in.next();
                        Integer i = Integer.valueOf(line);
                        if (numberList.remove(i)) {
                            System.out.printf("OK            [%s]", i);
                        } else if (numberListOrg.contains(i)) {
                            System.out.printf("NG 入力済の値。[%s]", i);
                        } else {
                            System.out.printf("NG 範囲外の値。[%s]", i);
                        }
                    }
                } catch (Exception e) {
                    System.out.printf("NG 文字 [%s]", line);
                }
                System.out.println();
            }
        }
        System.out.println("入力終了");
    }
}

実行コンソール

数値を入力してください。 [1, 2, 3, 4, 5, 6, 7, 8, 9] : 1
OK            [1]
数値を入力してください。 [2, 3, 4, 5, 6, 7, 8, 9] : 10
NG 範囲外の値。[10]
数値を入力してください。 [2, 3, 4, 5, 6, 7, 8, 9] : A
NG 文字 [A]
数値を入力してください。 [2, 3, 4, 5, 6, 7, 8, 9] : 1
NG 入力済の値。[1]
数値を入力してください。 [2, 3, 4, 5, 6, 7, 8, 9] : 2
OK            [2]
数値を入力してください。 [3, 4, 5, 6, 7, 8, 9] : 3
OK            [3]
数値を入力してください。 [4, 5, 6, 7, 8, 9] : 4
OK            [4]
数値を入力してください。 [5, 6, 7, 8, 9] : 5
OK            [5]
数値を入力してください。 [6, 7, 8, 9] : 6
OK            [6]
数値を入力してください。 [7, 8, 9] : 7
OK            [7]
数値を入力してください。 [8, 9] : 8
OK            [8]
数値を入力してください。 [9] : 9
OK            [9]
入力終了

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.55%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる