2009-03-27 38 views
0

Dies ist, was ich versuche zu tun: Ich lese eine Datei in der Befehlszeile ein. Die Datei enthält eine Liste von Daten, darunter sieht der Absatz aus. Das Problem, das ich habe, ist mit den if-Anweisungen.Array-Index außerhalb der Grenzen

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); 
     } 
    } 
} 

In Pseudo-Code wäre dies:

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. 
..... 

Die Probleme ist, dass ich eine arrayOutOfBounds Ausnahme mit dem Code zu erhalten Ich verwende.

Ich verstehe, dass j ++ ist was falsch ist, aber wie sonst soll ich durch die Zeichenfolge Array durchlaufen, so dass ich jede Zeile lesen und die entsprechenden Objekte erstellen kann? Ich weiß nicht, was ich tun soll. Ich brauche Hilfe.

foreign car 
aMarioy 
Mario's house 
(777) 777-7777 
[email protected] 
false 
black 
Italy 
4415.91 

truck 
aDougy 
Doug's house 
(123) 456-7890 
[email protected]ug.com 
30 
61234.56 
8/10/2003 

vehicle 
aRobby 
Rob's house 
(987) 654-3210 
[email protected] 

bicycle 
bTommy 
Tom's house 
(246) 810-1214 
[email protected] 
7 

truck 
bGeorge 
George's house 
(666) 666-6666 
[email protected] 
25 
51234.56 
12/4/2004 

vehicle 
bTim 
Tim's house 
(111) 111-1111 
[email protected] 

bicycle 
bJim 
Jim's house 
(555) 555-5555 
[email protected] 
5 

american car 
bJohn 
John's house 
(888) 888-8888 
[email protected] 
true 
green 
false 
true 

car 
cKen 
Ken's house 
(999) 999-9999 
[email protected] 
false 
orange 

foreign car 
cMario 
Mario's house 
(777) 777-7777 
[email protected] 
false 
black 
Italy 
4415.91 


american car 
gSam 
Sam's house 
(333) 333-3333 
[email protected] 
false 
blue 
true 
false 

Antwort

6

Ein paar Probleme:

  • Sie Inkrementieren j in beide "wenn" -Tests. Ich habe nicht überprüft, um sicher zu sein (es ist ziemlich verworren Code, um ehrlich zu sein), aber wenn Sie sicherstellen, dass Sie nur j erhöhen, wenn Sie ein Spiel gefunden haben, wird das helfen.
  • Ihr Test mit i bedeutet im Grunde, dass es versuchen wird, so viele Fahrzeuge wie Linien in der Datei zu lesen, anstatt zu stoppen, wenn Sie das Ende der Datei erreicht haben. Grundsätzlich brauchen Sie hier nicht i.

Hier ist eine geänderte Version:

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); 
     } 
    } 

Es wäre etwas sauberer sein, die Art einmal obwohl zu extrahieren - dann können Sie die Vergleiche separat tun:

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); 
     } 
    } 

Es ist immer noch nicht so recht, wie Ich würde es tun, aber es ist näher ...

Mein nächster Schritt wäre, den Scanner angemessener zu verwenden:

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)); 
    } 
    // ... 
} 

Dann machen Sie den Konstruktor für Fahrzeug, Auto usw. die Parsing direkt aus dem Scanner.

Der nächste Schritt wäre, die Konstruktion von der Iteration zu trennen.Einführung einer neuen Methode:

// 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)); 
} 
+0

scheint es ist interessant, wie viele „versuchen, diese stattdessen“ Vorschläge gepostet werden, bevor jemand erklärt die tatsächliche e Fehler. – Tomalak

+1

@Tomalak, Die Frage lautet: "Ich verstehe, dass j ++ falsch ist, aber wie soll ich sonst durch das String-Array iterieren, damit ich jede Zeile lesen und die entsprechenden Objekte erstellen kann?" – strager

+0

@strager: Stimmt, aber ich bezweifle, dass diese Zeile eine Anfrage nach Alternativen sein sollte. Die ganze Post hat "warum bekomme ich diese Ausnahme?" über alles geschrieben. – Tomalak

0

Setzen Sie Ihre Inkremente und Dekremente in ihre eigene Aussage. Dies wird den Code in den meisten Fällen leichter verständlich machen. In Ihrem Fall wird j++ zweimal aufgerufen, wenn der erste if ausfällt. Dies ist wahrscheinlich nicht das, was Sie wollen.

würde ich Ihre while Schleife in eine for Schleife, wie so konvertieren:

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

Wenn i == j immer nur die gleiche Variable für beide verwenden.

1

Jede Zeile, die nicht gleich „Fahrzeug“ tut, wird (fälschlicherweise) erhöht j so etwa nach Zeile 50 Sie erhalten die Ausnahme erhalten.

Es gibt mehrere Lösungen für dieses:

  • Increment j nur einmal pro Schleife.
  • Lesen Sie die Zeilen in eine andere ArrayList.
  • Lesen Sie die Zeilen nicht in eine Datenstruktur, sondern verarbeiten Sie sie so, wie sie gelesen werden. Auf diese Weise sind Sie unabhängiger von der Größe Ihrer Daten.
1

Verwenden Sie nicht j ++ im Index; inkrementieren Sie es einmal nach der gesamten Schleife, anstatt ein- oder zweimal, je nachdem, welche Bedingung erfüllt ist.

Wahrscheinlich besser, dies zu tun:

  • all in-line-Schritte ersetzen (x ++) mit Zuwachs Aussagen (x = x + 1)
  • herauszufinden, wohin sie gehen müssen, um den Code zu machen tun, was Sie wollen
  • sie zurückdrehen pre/post-Schritten inline, wenn Sie es Arbeit bekommen haben, wenn es angebracht
Verwandte Themen