Search code examples
javagenericsbufferstack-overflowbufferedreader

How Do I Fix This Instance of Stack Overflow Error?


I am meant to create a class with a static method which is required to do the following:

  1. return a Map which connects employee ID numbers and Employee objects, as stated in a text file
  2. have a toString method that returns the information about the employee that has the inputted ID number

I do believe I have nearly finished this assignment, however, my latest problem is a rather extreme case of StackOverflowError which I can't seem to identify a solution to. Here is the relevant information:

First, here's the class-provided, uneditable main class I am meant to write a class to conform to:

 public static void main(String[] args)  //this is line 6 for reference
  {
    Map<String, Employee> data = Employee.load(); 
    Scanner keyboard = new Scanner(System.in);
    System.out.println("Enter ID of employee you're looking for");
    String id = keyboard.nextLine();
    System.out.println(data.get(id));
  }

And here's the class I have written that should almost be ready to work as intended:

public Employee(String b) { //this is line 6 for reference
        Map<String, Employee> m=load();   //line 7
        if (m.containsKey(b)){
            String value=m.get(b).toString();
            System.out.println(b+" -> "+value);
        }
    }

    public static Map<String,Employee> load() {
        File f=new File("employees.txt");
        Map<String,Employee> result=new LinkedHashMap<>();
        String ID = null;
        String name = null;
        try {
            BufferedReader in = new BufferedReader(new FileReader(f)); //line 20
            String line;
            String[] values;
            int i=0;
            while(((line=in.readLine())!=null)){
                if (i>0){ //this skips the first line with irrelevant informaion
                line=in.readLine();
                values= line.split(" ", 2);
                ID=values[0];
                if (values.length>1){
                name= values[1].replaceAll("\\s{2,}"," ").trim();}}
                i++;}
        } catch (IOException e) {
            e.printStackTrace();
        }
        Employee e=  new Employee(name); //line 35
        result.put(ID, e);
        return result;
    }

An example of what should happen is that the program should work this way:

Output: Enter ID of employee you're looking for

Input: 39-7290036

Output: 39-7290036 -> Elroy Bevis [email protected]

but instead the program crashes before there is even the initial output of a request for input. The errors that occur are as follows:

Exception in thread "main" java.lang.StackOverflowError
    at java.base/java.nio.ByteBuffer.limit(ByteBuffer.java:265)
    at java.base/java.nio.Buffer.<init>(Buffer.java:223)
    at java.base/java.nio.ByteBuffer.<init>(ByteBuffer.java:284)
    at java.base/java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:63)
    at java.base/java.nio.ByteBuffer.allocate(ByteBuffer.java:351)
    at java.base/sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:264)
    at java.base/sun.nio.cs.StreamDecoder.<init>(StreamDecoder.java:244)
    at java.base/sun.nio.cs.StreamDecoder.forInputStreamReader(StreamDecoder.java:79)
    at java.base/java.io.InputStreamReader.<init>(InputStreamReader.java:74)
    at java.base/java.io.FileReader.<init>(FileReader.java:75)
    at Employee.load(Employee.java:20)
    at Employee.<init>(Employee.java:7) //these last two lines repeat for several upon several more lines
    at Employee.load(Employee.java:35) 

Solution

  • You are getting a stackoverflow exception because the load() method creates a new Employee object and inside the constructor for Employee load() gets called back and so on

    Your constructor for Employee should look something like

    public Employee(String id, String name) {
        this.id = id
        this.name = name
    }
    

    And you need to create a new Employee inside the while loop in load so add this at the end of the while loop just before the i++ line

    Employee employee = new Employee(ID, name);
    result.put(ID, employee);
    

    and remove the corresponding lines after the while loop