簡體   English   中英

數組索引超出范圍

[英]Array Index out of bounds

這就是我要執行的操作:我正在從命令行讀取文件。 該文件包含一個數據列表,此段下面是它的樣子。 我遇到的問題是if語句。

import java.util.*;
import java.io.*;

public class VehicleTest {
    public static void main(String[] args) throws FileNotFoundException {
        String vehicle = "vehicle";
        String car = "car";
        String americanCar = "american car";
        String foreignCar = "foreign car";
        String truck = "truck";
        String bicycle = "bicycle";

        File file = new File(args[0]);
        Scanner input = new Scanner(file);

        String[] autos = new String[100];
        ArrayList allVehicles = new ArrayList();


        for (int i = 0; i < autos.length; i++) {
            autos[i] = input.nextLine();
        }

        int j = 0;
        int i = 0;

        while (i++ < autos.length) {
            if (vehicle.equalsIgnoreCase(autos[j++])) {
                Vehicle v = new Vehicle();
                v.setOwnerName(autos[j]);
                allVehicles.add(v);
            }else if(car.equalsIgnoreCase(autos[j++])){
                Car c = new Car();
                c.setOwnerName(autos[j]);
                allVehicles.add(c);
            }
        }

        for(Object a: allVehicles){
            System.out.println(a);
        }
    }
}

用偽代碼可以是:

while i is less than the length of the string  array  
 if you see the word vehicle create a new vehicle object and add it to the arrayList.  
 if you see the word car create a new car object and add it to the arrayList.  
.....

問題是我使用的代碼出現了arrayOutOfBounds異常。

我知道j ++出了什么問題,但是我還應該如何遍歷字符串數組,以便可以讀取每一行並創建適當的對象? 我不知所措。 我需要協助。

foreign car  
aMarioy  
Mario's house  
(777) 777-7777  
gmario@mario.com  
false  
black  
Italy  
4415.91  

truck  
aDougy  
Doug's house  
(123) 456-7890  
hdoug@doug.com  
30  
61234.56  
8/10/2003  

vehicle  
aRobby  
Rob's house  
(987) 654-3210  
irob@rob.com  

bicycle  
bTommy  
Tom's house  
(246) 810-1214  
jtom@tom.com  
7  

truck  
bGeorge  
George's house  
(666) 666-6666  
kgeorge@george.com  
25  
51234.56  
12/4/2004  

vehicle  
bTim  
Tim's house  
(111) 111-1111  
tim@tim.com  

bicycle  
bJim  
Jim's house  
(555) 555-5555  
Ajim@jim.com  
5  

american car  
bJohn  
John's house  
(888) 888-8888  
Bjohn@john.com  
true  
green  
false  
true  

car  
cKen  
Ken's house  
(999) 999-9999  
Cken@ken.com  
false  
orange  

foreign car  
cMario  
Mario's house  
(777) 777-7777  
Dmario@mario.com  
false  
black  
Italy  
4415.91  


american car  
gSam  
Sam's house  
(333) 333-3333  
Hsam@sam.com  
false  
blue  
true  
false  

幾個問題:

  • 您在兩個“ if”測試中都將j遞增。 我尚未確定(老實說,這是很復雜的代碼),但是如果您確保只在找到匹配項時才遞增j,那會有所幫助。
  • 使用i測試基本上意味着它將嘗試讀取文件中包含行數的所有車輛,而不是在到達文件末尾時停止讀取。 基本上,您在這里不需要i

這是一個更改的版本:

    while (j < autos.length) {
        if (vehicle.equalsIgnoreCase(autos[j])) {
            j++;
            Vehicle v = new Vehicle();
            v.setOwnerName(autos[j++]);
            allVehicles.add(v);
        } else if(car.equalsIgnoreCase(autos[j])){
            j++;
            Car c = new Car();
            c.setOwnerName(autos[j++]);
            allVehicles.add(c);
        }
    }

一次提取類型會更清潔-然后您可以分別進行比較:

    while (j < autos.length) {
        String type = autos[j++];
        if (vehicle.equalsIgnoreCase(type)) {
            Vehicle v = new Vehicle();
            v.setOwnerName(autos[j++]);
            allVehicles.add(v);
        } else if(car.equalsIgnoreCase(type)){
            Car c = new Car();
            c.setOwnerName(autos[j++]);
            allVehicles.add(c);
        }
    }

它仍然不是我要怎么做,但距離更近了...

我的下一步是更適當地使用掃描儀:

while (scanner.hasNext()) {
    String type = scanner.nextLine();
    if (type.equalsIgnoreCase("vehicle")) {
        allVehicles.add(new Vehicle(scanner));
    } else if (type.equalsIgnoreCase("car")) {
        allVehicles.add(new Car(scanner));
    }
    // ...
}

然后,使Vehicle,Car等的構造函數直接從掃描儀進行解析。

下一步將是從迭代中分離出構造。 介紹一種新方法:

// Use a base type in real code
private static Object parseNextVehicle(Scanner scanner) {
    String type = scanner.nextLine();
    if (type.equalsIgnoreCase("vehicle")) {
        return new Vehicle(scanner);
    } else if (type.equalsIgnoreCase("car")) {
        return new Car(scanner);
    }
    // ... throw an exception indicating an unknown vehicle type
}

// ... and then in the main method, use it like this:
while (scanner.hasNextLine()) {
    allVehicles.add(parseNextVehicle(scanner));
}

每行不等於“車輛”的行都會(錯誤地)使j遞增,因此大約在第50行之后,您將獲得異常。

有多種解決方案:

  • 每個循環僅將j遞增一次。
  • 將這些行讀入另一個ArrayList
  • 不要將行讀入數據結構中,而應在讀取時對其進行處理。 這樣,您將更加獨立於數據大小。

不要在下標中使用j ++。 在整個循環后將其遞增一次,而不是一次或兩次,具體取決於哪種條件成立。

這樣做可能更好:

  • 將所有內聯增量(x ++)替換為增量語句(x = x + 1)
  • 弄清楚他們需要去使代碼執行您想要的操作的地方
  • 如果可行,將它們恢復為內聯前/后增量

將增量和減量放在自己的語句中。 在大多數情況下,這將使代碼更易於理解。

在您的情況下,如果第一個if失敗, j++被調用兩次。 這可能不是您想要的。

我會將您的while循環轉換為for循環,如下所示:

for (int i = 0, j = 0; i < autos.length; ++i, ++j) {
    if (vehicle.equalsIgnoreCase(autos[j])) {
        // ...

如果總是i == j ,則對兩者都使用相同的變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM