【问题标题】:java.lang.ArrayIndexOutOfBoundsException when trying to read from File尝试从 File 读取时出现 java.lang.ArrayIndexOutOfBoundsException
【发布时间】:2019-11-24 01:19:00
【问题描述】:

所以基本上我得到了一个问题:

创建将读取 members.txt 文件内容的程序。成员必须分为 3 个阵列,每个团队一个。处理完所有成员后,向终端输出每个团队有多少成员以及团队队长的姓名的信息。文件值以逗号分隔,具有以下架构:

first_name, last_name, team_name, is_captain

这是我想出的代码(关于效率的问题,因为我还是个新手):

package ssst.edu.ba;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scan = new Scanner("members.txt");
        int rcount = 0, bcount = 0, gcount = 0;
        ArrayList<Student> red = new ArrayList<Student>(5);
        ArrayList<Student> blue = new ArrayList<Student>(5);
        ArrayList<Student> green = new ArrayList<Student>(5);
        String line;
        String rCap = "";
        String bCap = "";
        String gCap = "";

        while ((line = scan.nextLine()) != null) {
            String[] obj = line.split(", ");
            if(obj[2] == "Red") {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                red.add(a);
                rcount++;
                if(obj[3] == "true") {
                    rCap = obj[0] + obj[1];
                }
            }
            else if (obj[2] == "Blue") {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                blue.add(a);
                bcount++;
                if(obj[3] == "true") {
                    bCap = obj[0] + obj[1];
                }
            }
            else {
                Student a = new Student(obj[0],obj[1],obj[2],Boolean.parseBoolean(obj[3]));
                green.add(a);
                gcount++;
                if(obj[3] == "true") {
                    gCap = obj[0] + obj[1];
                }
            }
        }
        System.out.println("There are " + rcount + " people on the red team.");
        System.out.println("There are " + bcount + " people on the blue team.");
        System.out.println("There are " + gcount + " people on the green team.");
        System.out.println("The captain for the red team is: " + rCap);
        System.out.println("The captain for the blue team is: " + bCap);
        System.out.println("The captain for the green team is: " + gCap);
    }
}

“Student”类很简单,它有 3 个私有 String 属性和一个私有 bool 值,它还有一个带有 4 个参数的构造函数,用于将值设置为文本文档“members.txt”中给出的值

文本文档如下所示:

Ginny, Gullatt, Blue, false
Tiara, Curd, Red, false
Camie, Poorman, Green, false
Jammie, Hasson, Green, false
Lionel, Hailey, Blue, false
Genevive, Mckell, Red, true
Esteban, Slaubaugh, Blue, false
Elden, Harte, Red, false
Tasia, Rodrigue, Green, false
Nathanial, Dentler, Red, false
Valda, Nicoletti, Blue, false
Kary, Wilkerson, Green, false
Coletta, Akey, Blue, false
Wilmer, Jack, Red, false
Loreta, Agnew, Green, true
Suzy, Cleveland, Red, false
Pasty, Laprade, Blue, false
Candie, Mehaffey, Green, false
Glady, Landman, Blue, true
Tierra, Mckeown, Red, false
Glady, Laprade, Green, false

问题:我收到此异常消息

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 1

我不知道这是否与 ArrayList 或字符串数​​组“obj”相关联,我也不知道如何修复它。

【问题讨论】:

  • 在此处发布的代码中,您只能按索引访问obj,这就是您的异常的来源。在您的输入文件中的某个时刻,您会得到一个只有一个值(没有逗号)的行,并且尝试访问 obj[2] 会得到那个异常。您应该检查line 包含的内容,并首先检查obj 的长度。
  • 可能与您的问题无关,但您最终会遇到的问题:您不应该使用 == 比较字符串。 Use .equals() instead.
  • 您能提供一个members.txt 内容示例吗?
  • 我刚刚添加了 members.txt,感谢您的提示!
  • 其他人已经解决了你的直接问题,所以我将把自己限制在一个一般性建议:熟悉你的调试器。 (我假设 IDEA Ultimate 有一个调试器;如果没有,您可能想尝试一个有调试器的 IDE。)如果您使用调试器一次单步执行代码,您将确切地看到它失败的地方,并且,通过将变量中的实际值与您认为的值进行比较,您将了解哪里出了问题。您也不必绕道 StackOverflow 并可以继续编码 :-)

标签: java arrays sorting arraylist split


【解决方案1】:

要将 Scanner 与文件一起使用,您必须通过 File 类提供文件,如下所示:

import java.io.File;
import java.io.FileNotFoundException;

public static void main(String[] args) throws FileNotFoundException {
    Scanner scan = new Scanner(new File("./members.txt"));

    /* ...Some code */
}

实际上,您正在从只包含文本“members.txt”的流中读取

扫描器(字符串源)

构造一个新的扫描器,生成从指定字符串扫描的值。

所以你正在使用构造函数 htat 接收一个字符串作为参数,而不是使用文件的那个。看https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#Scanner(java.lang.String)

您还必须使用hasNextLine 函数,例如:

while (scan.hasNextLine()) {
    line = scan.nextLine();

/* some code */

}

否则你会得到异常java.util.NoSuchElementException

这是您的程序的工作版本:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class Main {

    public static void main(String[] args) throws FileNotFoundException {
        Scanner scan = new Scanner(new File("./members.txt"));

        ArrayList<Student> red = new ArrayList<Student> (5);
        ArrayList<Student> blue = new ArrayList<Student> (5);
        ArrayList<Student> green = new ArrayList<Student> (5);

        // we use a map to save the index where is the captain in the array list
        HashMap<String,Integer> captains = new HashMap <String, Integer> ();

        while (scan.hasNextLine()) {
            String[] rawStudent = scan.nextLine().split(", ");
            Student student = new Student(rawStudent);

            ArrayList selectedTeam = red;

            // we select dynamically the list where the student will be added
            switch (student.getTeam()) {
                case "Red": selectedTeam = red; break;
                case "Blue": selectedTeam = blue; break;
                case "Green": selectedTeam = green; break;
            }

            selectedTeam.add(student);

            if (student.isCaptain()) {
                int lastAddedIndex = selectedTeam.size() - 1;

                captains.put(student.getTeam(), lastAddedIndex);
            }
        }

        System.out.println("There are " + red.size() + " people on the red team.");
        System.out.println("There are " + blue.size() + " people on the blue team.");
        System.out.println("There are " + green.size() + " people on the green team.");

        System.out.println("The captain for the red team is: " + red.get(captains.get("Red")).getFullName());
        System.out.println("The captain for the blue team is: " + blue.get(captains.get("Blue")).getFullName());
        System.out.println("The captain for the green team is: " + green.get(captains.get("Green")).getFullName());
    }
}

class Student {
    private String name;
    private String lastName;
    private String team;
    private boolean isCaptain;

    public Student(String p1, String p2, String p3, boolean p4) {
        this.name = p1;
        this.lastName = p2;
        this.team = p3;
        this.isCaptain = p4;
    }

    public Student(String[] list) {
        this(list[0], list[1], list[2], Boolean.parseBoolean(list[3]));
    }

    public String getFullName() {
        return this.name + " " + this.lastName;
    }

    public boolean isCaptain() {
        return this.isCaptain;
    }

    public String getTeam() {
        return this.team;
    }
}

希望对你有帮助。

【讨论】:

    【解决方案2】:

    我已经制作了一个与此类似的程序,其中我正在读取不同格式的文件,例如 CSV EXCEL 等并对其执行操作,因此您可以检查代码是行业级代码,并且会提供更多曝光而不是只为您的解决方案。

    https://github.com/NahidAkhter/feeCalculator.git
    

    简而言之,我可以在下面给出一个 sn-p 1) TextTransctionReader.java

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    
    import com.feecalculator.Constant.FILETYPE;
    import com.feecalculator.Transaction;
    
    
    public class TextTransctionReader extends AbstractTransactionReader implements ITransactionManager {
    
    
        @Override
        public void readTransaction(File transactionFile) {
    
    
            BufferedReader br = null;
            String line = "";
            String cvsSplitBy = ",";
    
            try {
    
                br = new BufferedReader(new FileReader(transactionFile));
                while ((line = br.readLine()) != null) {
                    String[] transactionAttributes = line.split(cvsSplitBy);
                    Transaction transaction = getTransaction(transactionAttributes); 
                    saveTransaction(transaction);
    
                }        
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    
        @Override
        public ITransactionManager readFile(FILETYPE fileType) {
            if(fileType == FILETYPE.TEXT){
                return TrasactionReader.getTrasactionReaderInstance().readTextFile();
            }
            return null;
        }
    
    
    }
    
    

    主类如下:

    import java.io.File;
    
    import com.feecalculator.Constant.FILETYPE;
    import com.feecalculator.reader.ITransactionManager;
    import com.feecalculator.reader.TrasactionReader;
    
    
    public class MainFeeCalculator {
        public static void main(String[] args) {
    
            File transactionfile = new File(new File("").getAbsolutePath(),"resource/Input_java.xlsx");
            ITransactionManager tranction= TrasactionReader.getTrasactionReaderInstance().readFile(FILETYPE.EXCEL,transactionfile);     
            tranction.displayTransactionReport();   
    
    
        }
    }
    

    希望这能解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      相关资源
      最近更新 更多