メソッド updateEmployees(PersonnelManager pm) はテキスト ファイルを読み取り、ファイルの各行の最初の文字 (3 つの可能性があります) に応じて、異なるコードを実行します。PersonnelManager クラスと Employee クラスは問題に関与していません。そのため、ここではそれらを含めません。サンプル入力ファイルは次のとおりです。
n メザリラ、ルーカス h 40000
r5
キンゼイ
n プライス、レーン s 50
r4
メソッドは次のとおりです: (File オブジェクトと Scanner オブジェクトはメソッドの外で宣言されます)
public static boolean updateEmployees(PersonnelManager pm) {
try
{
file = new File(updates);
in = new Scanner(file);
}
catch (FileNotFoundException e)
{
System.out.println("Could not load update file.");
return false;
}
int currentLine = 1; //Keep track of current line being read for error reporting purpose
while (in.hasNext()) {
String line = in.nextLine();
//Check the type of update the line executes
//Update: Add new Employee
if (line.charAt(0) == 'n') {
String[] words = line.split("\\s"); //Split line into words. Index [0]: update type. [1]: last name. [2]: first name. [3]: employee type. [4]: wage.
words[1] = words[1].substring(0, words[1].length() - 1); //remove comma from last name
if (words.length != 5) { //If there are not 5 words or tokens in the line, input is incorrect.
System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
return false;
}
if (words[3].equals("s")) //if employee is type SalariedEmployee
pm.addEmployee(new SalariedEmployee(words[2], words[1], Double.parseDouble(words[4])));
else if (words[3].equals("h")) //if employee is type HourlyEmployee
pm.addEmployee(new HourlyEmployee(words[2], words[1], Double.parseDouble(words[4])));
else {
System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
return false;
}
//Display information on the console
System.out.println("New Employee added: " + words[1] + ", " + words[2]);
}
//Update: Raise rate of pay
if (line.charAt(0) == 'r') {
String[] words = line.split("\\s"); //Split line into words. Index [0]: update type. [1]: rate of wage raise
if (Double.parseDouble(words[1]) > 100.0) { //If update value is greater than 100
System.out.println("Error in line:" + currentLine + ". Wage raise rate invalid.");
return false;
}
for (int i =0; i<pm.howMany(); i++) { //Call raiseWages() method for all employees handled by the pm PersonnelManager
pm.getEmployee(i).raiseWages(Double.parseDouble(words[1]));
}
//Display information on the console
System.out.println("New Wages:");
pm.displayEmployees();
}
//Update: Dismissal of Employee
if (line.charAt(0) == 'd') {
String[] words = line.split("\\s"); //Split line into words. Index [0]: update type. [1]: last name of employee
if (words.length != 2) { //If there are not 2 words or tokens in the line, input is incorrect.
System.out.println("Could not update. File contains incorrect input at line: " + currentLine);
return false;
}
String fullName = pm.getEmployee(words[1]).getName(); //Get complete name of Employee from last name
pm.removeEmployee(words[1]);
//Display information on the console
System.out.println("Deleted Employee: " + fullName);
}
currentLine++;
}
return true;
}
入力ファイルには 5 行あるので、while ループは 5 回実行されるはずですが、そうはなりません。入力ファイルの 4 行目「n Pryce, Lane s 50」に到達すると、コードの 25 行目で「java.lang.StringIndexOutOfBoundsException」エラーが発生します。
問題は 24 行目と 25 行目で発生します。
String[] words = line.split("\\s"); //Split line into words. Index [0]: update type. [1]: last name. [2]: first name. [3]: employee type. [4]: wage.
words[1] = words[1].substring(0, words[1].length() - 1); //remove comma from last name
入力の 4 行目では、"line" 文字列が 5 つの文字列に分割されていません。これはwords[0]にあり、「n」に等しい1つにのみ分割されます。私が理解できないのは、プログラムが同じコード行を使用して、入力の最初の 3 行の文字列を分割したことです。4 行目で機能しないのはなぜですか?
入力ファイルを次のように変更すると
n メザリラ、ルーカス h 40000
r5
キンゼイ
コマンド「n」の2番目の出現を削除すると、機能します。実際、同じコマンド (「n」、「r」、または「d」) を複数回使用する入力ファイルを使用するたびに、コマンドが 2 回目に発生する行は 1 つの文字列にのみ分割されます。行の最初のトークン (int この場合は "n"、"r"、または "d") を含みます。
説明が明確だったことを願っています。なぜこれが起こるのか知っている人がいたら、助けてください。