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

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

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

Q&A

解決済

1回答

1336閲覧

java.lang.IndexOutOfBoundsExceptionの解決方法

inori333

総合スコア4

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ArrayList

Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

0グッド

1クリップ

投稿2022/09/14 08:41

編集2022/09/14 11:39

前提

ここに質問の内容を詳しく書いてください。
arraylistに入っている車を検索するシステムを作っているときにエラーが発生し、そのエラーの解決方法がわからないので教えてほしいです。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • carsearch_0でそれぞれのif文を正しく実行しエラーで強制終了しないようにしたい

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

車種名を入力してください クラウン 名前:クラウン,値段:4350000円 オプション一覧 キーレス,スマートキー,パワーウィンドウ,ベンチシート,シートヒーター,シートクーラー,本革シート,Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 8 out of bounds for length 0 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248) at java.base/java.util.Objects.checkIndex(Objects.java:372) at java.base/java.util.ArrayList.get(ArrayList.java:459) at Car_register.carsearch_0(Car_register.java:127) at CarOption.search_0(CarOption.java:50) at Main.main(Main.java:21)

該当のソースコード

import java.io.IOException; import java.util.ArrayList; import java.nio.file.Files; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; public class CarOption extends Car_register{ private String[] status = new String[27]; private String fail; static String name; Scanner sc = new Scanner(System.in); CarOption(String name) { this.fail = name; } //車の登録 public void registration() { Path inputFilePath = Paths.get(this.fail); try { ArrayList<String> lines = (ArrayList<String>) Files.readAllLines(inputFilePath, StandardCharsets.UTF_8); for (String line : lines) { this.status = line.split(","); for (int i = 0; i < status.length; i++) { if (i == 11) { System.out.println(status[i]); } else { System.out.printf("%s,", status[i]); } } register(status); } System.out.println(""); } catch (IOException e) { System.out.println("読み込みに失敗しました"); System.out.println("プログラムを終了します"); System.out.println(e); System.exit(0); } } public void search_0(){ System.out.println("車種名を入力してください"); name = sc.nextLine(); Car_register.carsearch_0(this.name); } public void search_1(){ System.out.println("上限金額を入力してください"); int price_max = Integer.parseInt(sc.nextLine()); System.out.println("下限金額を入力してください"); int price_min = Integer.parseInt(sc.nextLine()); // Car_register.migration(); Car_register.carsearch_1(price_max, price_min); } public void search_2(){ // Car_register.migration(); } } import java.util.ArrayList; public class Car_register { //車のオプション static ArrayList<String> name = new ArrayList<String>(); static ArrayList<Integer> price = new ArrayList<Integer>(); static ArrayList<Integer> key = new ArrayList<Integer>(); static ArrayList<Integer> smart = new ArrayList<Integer>(); static ArrayList<Integer> power = new ArrayList<Integer>(); static ArrayList<Integer> sheet = new ArrayList<Integer>(); static ArrayList<Integer> heater = new ArrayList<Integer>(); static ArrayList<Integer> cooler = new ArrayList<Integer>(); static ArrayList<Integer> leather = new ArrayList<Integer>(); static ArrayList<Integer> ottoman = new ArrayList<Integer>(); static ArrayList<Integer> three = new ArrayList<Integer>(); static ArrayList<Integer> monitor = new ArrayList<Integer>(); static String car_data[] = new String[27]; static int car_price[] = new int[27]; static int car_key[] = new int[27]; static int car_smart[] = new int[27]; static int car_sheet[] = new int[27]; static int car_power[] = new int[27]; static int car_heater[] = new int[27]; static int car_cooler[] = new int[27]; static int car_leather[] = new int[27]; static int car_ottoman[] = new int[27]; static int car_monitor[] = new int[27]; static int car_three[] = new int[27]; static int cnt = 0; static int cnt2 = 0; public void register(String status[]) { for (int i = 0; i < 11; i++) { if (i == 0) { this.name.add(status[i]); } else if (i == 1) { this.price.add(Integer.parseInt(status[i])); } else if (i == 2) { this.key.add(Integer.parseInt(status[i])); } else if (i == 3) { this.smart.add(Integer.parseInt(status[i])); } else if (i == 4) { this.power.add(Integer.parseInt(status[i])); } else if (i == 5) { this.sheet.add(Integer.parseInt(status[i])); } else if (i == 6) { this.heater.add(Integer.parseInt(status[i])); } else if (i == 7) { this.cooler.add(Integer.parseInt(status[i])); } else if (i == 8) { this.leather.add(Integer.parseInt(status[i])); } else if (i == 9) { this.ottoman.add(Integer.parseInt(status[i])); } else if (i == 10) { this.three.add(Integer.parseInt(status[i])); } else if (i == 11) { this.monitor.add(Integer.parseInt(status[i])); } } } public void display() { System.out.println("車一覧"); for (int i = 0; i < 27; i++) { System.out.println(name.get(i)); } } static void carsearch_0(String car_name){ for(int i = 0; i < name.size(); i++){ if(car_name.equals(name.get(i)) && name.size() > i){ System.out.println("名前:" + name.get(i) + "," + "値段:" + price.get(i) + "円"); cnt2++; System.out.println("オプション一覧"); if(key.get(i) == 1){ System.out.printf("キーレス,"); cnt++; } if(smart.get(i) == 1){ System.out.printf("スマートキー,"); cnt++; } if(power.get(i) == 1){ System.out.printf("パワーウィンドウ,"); cnt++; } if(sheet.get(i) == 1){ System.out.printf("ベンチシート,"); cnt++; } if(heater.get(i) == 1){ System.out.printf("シートヒーター,"); cnt++; } if(cooler.get(i) == 1){ System.out.printf("シートクーラー,"); cnt++; } if(leather.get(i) == 1){ System.out.printf("本革シート,"); cnt++; } if(three.get(i) == 1){ System.out.printf("3列シート,"); cnt++; } if(monitor.get(i) == 1){ System.out.println("後席モニター"); cnt++; } if(cnt == 0){ System.out.println("オプションはありません"); } cnt = 0; }else{ if(i == 26 && cnt2 == 0){ System.out.println("該当する車種は存在しません"); cnt2 = 0; } } } } } import java.util.Scanner; public class Main { public static void main(String[] args){ CarOption car = new CarOption(args[0]); car.registration(); Scanner sc = new Scanner(System.in); System.out.println("/MENU/"); System.out.println("「0」車一覧「1」検索「2」終了 "); int a = Integer.parseInt(sc.next()); while (true) { if (a == 0) { car.display(); } else if (a == 1) { System.out.println("検索の仕方を選択してください"); System.out.println("「0」車種名「1」値段「2」オプション"); int b = Integer.parseInt(sc.next()); if(b == 0){ car.search_0(); }else if(b == 1){ car.search_1(); }else if(b == 2){ car.search_2(); } } else if (a == 2) { System.out.println("ありがとうございました"); break; } System.out.println("/MENU/"); System.out.println("「0」車一覧「1」検索「2」終了 "); a = Integer.parseInt(sc.next()); } sc.close(); } } アルファード,3597000,1,1,1,0,1,0,0,1,1,1 ハイエース,2903600,1,1,1,0,0,0,0,0,1,0 プリウス,2597000,1,1,1,0,1,0,1,0,0,0 ハリアー,2990000,1,1,1,1,1,0,0,0,0,0 ランドクルーザー,5100000,1,1,1,1,1,0,1,0,1,0 アクア,1980000,1,1,1,0,0,0,0,0,0,0 ヴォクシー,3090000,1,1,1,0,1,0,0,0,1,0 ヴェルファイア,4306000,1,1,1,0,0,0,0,1,1,1 クラウン,4350000,1,1,1,1,1,1,1,0,0,0 GR86,2799000,1,1,1,0,1,0,0,0,0,0 ノア,2670000,1,1,1,0,0,0,0,0,1,0 シエンタ,1818500,1,1,1,0,0,0,0,0,1,0 ハイラックス,4312000,1,1,1,0,0,0,0,0,0,0 RAV4,2774000,1,1,1,0,0,0,0,0,0,0 ヤリスクロス,1896000,1,1,1,0,0,0,0,0,0,0 ライズ,1707000,1,1,1,0,1,0,0,0,0,0 ルーミー,1556500,1,1,1,0,1,0,0,0,0,0 カローラスポーツ,2169000,1,1,1,0,0,0,0,0,0,0 パッソ,1265000,1,0,1,0,1,0,0,0,0,0 カムリ,3495000,1,1,1,1,0,0,0,0,0,0 カローラフィールダー,1709400,1,1,1,0,0,0,0,0,0,0 カローラクロス,1999000,1,0,1,0,0,0,0,0,0,0 カローラツーリング,2013000,1,1,1,0,1,0,0,0,0,0 スープラ,4995000,1,1,1,1,1,0,0,0,0,0 C-HR,2792000,1,1,1,0,1,0,0,0,0,0 MIRAI,7100000,1,1,1,1,1,1,1,0,0,0 コペン,2382200,1,1,1,0,1,0,0,0,0,0

試したこと

まず、CarOptionクラスのsearch_0で車種名を入力し、それを引数にしCar_registerクラスのcarsearch_0を実行した際に上に載せたようなエラーが出てしまいました。

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2022/09/14 10:14

「Car_registerクラスの127行目」はどれですか?
jimbe

2022/09/14 10:41 編集

IndexOutOfBoundsException が何なのかは分かっておられるのでしょうか。 > ソースコードの欄で「------」で区切っています マークダウンで分けてください。 そのようにされるとこちらでテストする際に編集する必要があり、間違いが入り込む可能性がある等の余計な心配・手間がかかります。 …と思ったら、Main.java が無いので実行自体出来ないです。 車のデータファイルも必要ですね。
BeatStar

2022/09/14 11:41

> java.lang.IndexOutOfBoundsExceptionの解決方法 ■ 例外メッセージを読む ■ デバッグをする しかないかと。
inori333

2022/09/14 11:47

BeatStarさん回答ありがとうございます。長さが0のArraylistを参照しているから今回のエラーが起きているのはわかるんですが、今回用意したデータはちゃんとArraylistに入っているのでなぜ長さが0のところを参照しているのかがわからず、解決方法もわからない感じです。
jimbe

2022/09/14 12:29 編集

> 今回用意したデータはちゃんとArraylistに入っているので 入っていない所があります。 入れている個所に print を仕込む等してみてください。 表示されない=通っていない=入っていない個所が見つかるはずです。 例外は if(monitor.get(i) == 1){ System.out.println("後席モニター"); cnt++; } の if 文で発生しています。
jimbe

2022/09/14 12:31

コードは ``` の行で挟むことで枠内にコードが入るようになります。 個々のソースコードやファイルを個々に ``` で挟むようにして頂ければ、それぞれ毎にコピー出来るようになります。
inori333

2022/09/14 12:37

jimbeさん、回答ありがとうございます。後席モニターの部分で例外が出ていることがわかったおかげで解決することが出来ました。 Car_registerクラスの35行目のfor文で繰り返す回数が1回少なく後席モニターのデータが入っていませんでした。
kazuma-s

2022/09/14 13:42

for文を使う必要はありません。次のように書くべきです。 public void register(String status[]) {   this.name.add(status[0]);   this.price.add(Integer.parseInt(status[1]));   this.key.add(Integer.parseInt(status[2]));   ...   this.monitor.add(Integer.parseInt(status[11])); }
jimbe

2022/09/14 16:44

どこで例外が発生したかは、例外のメッセージ内にスタックトレースとして表示されています。(swordone さんが真っ先に指摘されています。) 場所さえ分かればということですので、是非スタックトレースもチェックするようにしてください。
swordone

2022/09/14 17:21

まずこれこんな頭がおかしくなりそうなコードやめてCarクラスみたいなのを作りたい
guest

回答1

0

ベストアンサー

今回用意したデータはちゃんとArraylistに入っているので

入っていない所があります。
入れている個所に print を仕込む等してみてください。
表示されない=通っていない=入っていない個所が見つかるはずです。

例外は
if(monitor.get(i) == 1){
System.out.println("後席モニター");
cnt++;
}
の if 文で発生しています。


csv ファイルを縦割りで列毎に別々の変数(List)にするのではなく、行が表すクラスを想定してそのオブジェクトの集まりを扱うようにするのがオブジェクト指向のやり方です。

27 とか 11 とかの数値をそのままあちこちに散りばめていると、例えば csv のデータが増えた/減った場合に直すのが大変です。
ファイルに書かれている件数であれば、ファイルを読んで1行(件)ずつ List に入れていればデータの件数はその List のサイズとして取れます。
オプションの数は、下コードの Car.Option のようにオプションを管理するクラスを用意することで知ることが出来ます。

オプションのように有無を判断するだけのものは、 enum と Set(EnumSet) が使えます。

検索には、オブジェクト群を巡回するコードに条件判断のオブジェクトを渡す形にすると、似た/同じコードを何度も書かずに済みます。

CarDealer.java

java

1import java.io.IOException; 2import java.nio.charset.StandardCharsets; 3import java.nio.file.Files; 4import java.nio.file.Paths; 5import java.util.*; 6import java.util.function.Predicate; 7 8public class CarDealer { 9 public static void main(String[] args) { 10 CarDealer dealer = null; 11 try { 12 dealer = new CarDealer("cars.csv"); //args[0] 13 } catch(IOException e) { 14 System.out.println("読み込みに失敗しました"); 15 System.out.println("プログラムを終了します"); 16 e.printStackTrace(); 17 return; 18 } 19 20 try(Scanner sc = new Scanner(System.in)) { 21 while(true) { 22 System.out.println("/MENU/"); 23 System.out.println("「0」車一覧「1」検索「2」終了 "); 24 int a = Integer.parseInt(sc.nextLine()); 25 26 if(a == 0) { 27 dealer.printList(); 28 } else if(a == 1) { 29 System.out.println("検索の仕方を選択してください"); 30 System.out.println("「0」車種名「1」値段「2」オプション"); 31 int b = Integer.parseInt(sc.nextLine()); 32 33 if(b == 0) { 34 System.out.println("車種名を入力してください"); 35 String name = sc.nextLine(); 36 dealer.search(name); 37 } else if(b == 1) { 38 System.out.println("上限金額を入力してください"); 39 int price_max = Integer.parseInt(sc.nextLine()); 40 System.out.println("下限金額を入力してください"); 41 int price_min = Integer.parseInt(sc.nextLine()); 42 dealer.search(price_max, price_min); 43 } else if(b == 2) { 44 System.out.println("欲しいオプションを一つ選んでください"); 45 StringBuilder sb = new StringBuilder(); 46 for(int i=0; i<Car.Option.values().length; i++) { 47 sb.append("「").append(i).append("」").append(Car.Option.values()[i].name); 48 } 49 System.out.println(sb.toString()); 50 int i = Integer.parseInt(sc.nextLine()); 51 dealer.search(Car.Option.values()[i]); 52 } 53 } else if(a == 2) { 54 break; 55 } 56 } 57 System.out.println("ありがとうございました"); 58 } 59 } 60 61 static class Car { 62 enum Option { 63 KEY("キーレス"), SMART("スマートキー"), POWER("パワーウィンドウ"), SHEET("ベンチシート"), HEATER("シートヒーター"), 64 COOLER("シートクーラー"), LEATHER("本革シート"), OTTOMAN("OTTOMAN"), THREE("3列シート"), MONITOR("後席モニター"); 65 66 final String name; 67 Option(String name) { 68 this.name = name; 69 } 70 } 71 72 final String name; 73 final int price; 74 final Set<Option> options; 75 76 Car(String name, int price, Set<Option> options) { 77 this.name = name; 78 this.price = price; 79 this.options = Set.copyOf(options); 80 } 81 82 void print() { 83 System.out.println("名前: " + name); 84 System.out.println("値段: " + String.format("%,d円", price)); 85 System.out.print("オプション: "); 86 StringJoiner sj = new StringJoiner(","); 87 sj.setEmptyValue("(無し)"); 88 for(Car.Option option : options) sj.add(option.name); 89 System.out.println(sj.toString()); 90 } 91 } 92 93 private List<Car> carList = new ArrayList<>(); 94 95 CarDealer(String filename) throws IOException { 96 List<String> lines = Files.readAllLines(Paths.get(filename), StandardCharsets.UTF_8); 97 for(String line : lines) carList.add(parseCSV(line)); 98 } 99 100 private Car parseCSV(String line) throws NumberFormatException { 101 String[] tokens = line.split(","); 102 103 String name = tokens[0]; 104 int price = Integer.parseInt(tokens[1]); 105 Set<Car.Option> options = EnumSet.noneOf(Car.Option.class); 106 for(int i=0; i<Car.Option.values().length; i++) { 107 if(Integer.parseInt(tokens[2+i]) == 1) options.add(Car.Option.values()[i]); 108 } 109 110 return new Car(name, price, options); 111 } 112 113 void printList() { 114 System.out.println("車一覧"); 115 for(Car car : carList) System.out.println(car.name); 116 } 117 118 void search(String name){ 119 searchAndPrint(car -> car.name.equals(name)); 120 } 121 122 void search(int max, int min){ 123 searchAndPrint(car -> min <= car.price && car.price <= max); 124 } 125 126 void search(Car.Option option){ 127 searchAndPrint(car -> car.options.contains(option)); 128 } 129 130 private void searchAndPrint(Predicate<Car> predicater) { 131 boolean found = false; 132 for(Car car : carList) { 133 if(predicater.test(car)) { 134 car.print(); 135 found = true; 136 } 137 } 138 if(!found) { 139 System.out.println("該当する車種は存在しません"); 140 } 141 } 142}

実行結果

plain

1/MENU/ 2「0」車一覧「1」検索「2」終了 31 4検索の仕方を選択してください 5「0」車種名「1」値段「2」オプション 60 7車種名を入力してください 8クラウン 9名前: クラウン 10値段: 4,350,000円 11オプション: キーレス,スマートキー,パワーウィンドウ,ベンチシート,シートヒーター,シートクーラー,本革シート 12/MENU/ 13「0」車一覧「1」検索「2」終了 141 15検索の仕方を選択してください 16「0」車種名「1」値段「2」オプション 171 18上限金額を入力してください 191000000 20下限金額を入力してください 212000000 22該当する車種は存在しません 23/MENU/ 24「0」車一覧「1」検索「2」終了 251 26検索の仕方を選択してください 27「0」車種名「1」値段「2」オプション 282 29欲しいオプションを一つ選んでください 30「0」キーレス「1」スマートキー「2」パワーウィンドウ「3」ベンチシート「4」シートヒーター「5」シートクーラー「6」本革シート「7」OTTOMAN「8」3列シート「9」後席モニター 319 32名前: アルファード 33値段: 3,597,000円 34オプション: キーレス,スマートキー,パワーウィンドウ,シートヒーター,OTTOMAN,3列シート,後席モニター 35名前: ヴェルファイア 36値段: 4,306,000円 37オプション: キーレス,スマートキー,パワーウィンドウ,OTTOMAN,3列シート,後席モニター 38/MENU/ 39「0」車一覧「1」検索「2」終了 402 41ありがとうございました

投稿2022/09/15 02:46

編集2022/09/15 06:57
jimbe

総合スコア12616

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問