数组索引超出范围

时间:2009-03-27 14:39:55

标签: java

这就是我要做的事情:我正在从命令行读取文件。 该文件包含一个数据列表,下面这段是它的样子。 我遇到的问题是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  

4 个答案:

答案 0 :(得分:6)

有几个问题:

  • 你在两个“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));
}

答案 1 :(得分:1)

每一行不等于“车辆”的行都会(错误地)递增j所以大约在第50行之后你会得到例外。

有多种解决方案:

  • 每个循环只增加一次j
  • 将这些行读入另一个ArrayList
  • 不要将这些行读入数据结构,而是在读取它们时对其进行处理。这样,您就可以更加独立于数据的大小。

答案 2 :(得分:1)

不要在下标中使用j ++;在整个循环之后递增一次,而不是根据哪个条件保持一次或两次。

可能更好地做到这一点:

  • 用增量语句(x = x + 1)
  • 替换所有的内联增量(x ++)
  • 找出他们需要去做代码的地方
  • 如果看起来合适,
  • 将它们恢复为内联前/后增量

答案 3 :(得分:0)

将增量和减量放在自己的陈述中。这将使代码在大多数情况下更容易理解。

在您的情况下,如果第一个j++失败,则会if被调用两次。这可能不是你想要的。

我会将您的while循环转换为for循环,如下所示:

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

总是i == j,只需对两者使用相同的变量。