Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solve Java heap space error when adding new values to double Arraylist

Context

I have an assignment that is asking me to read a recipe from a text file and manipulate the contents like units of measurement and ingredient quantity's. I have manged to split the recipe into three arraylists, and now have to start converting imperial units to metric. But when I try to multiply and convert the corresponding units I get the Java heap space error. I looked online how to fix this and realized it may have something to do with arraylists leaking memory or using to much space. The issue is I have no clue where this might occur, and have already tried using float lists or integer lists instead of doubles and it still hasn't worked, as I still need to use decimals. I know that the string conversion to ml works, but don't know if the corresponding conversion with numbers does, any help would be greatly appreciated.

Code

import java.util.*;
import java.io.*;
class Main {
    /**
     * Prints methods to user
     */
    public static void main(String[] args) throws Exception{
        servingReader();
        System.out.println(sSize);
        ingrReader();
        System.out.println(ingrList);
        ingrSeperator();
        System.out.println(ingrSeperatorList);
        System.out.println(ingrSeperatorList.get(7));
        divide();
        System.out.println(ingrSeperatorList);
        converter();
        System.out.println(ingrList);
        System.out.print(ingrSeperatorList);
        multiply();
        System.out.print(ingrSeperatorList);
    }//end main

    static int sSize;//int for serving size

    /**
     * Reads text file
     */
    public static void servingReader() throws Exception{

        //recipe read
        File recipe = new File("/home/runner/recipe.txt");
        Scanner sc = new Scanner(recipe);

        //loop to find serving size
        while(sc.hasNextLine()){
            String s = sc.nextLine().toUpperCase();
            if(s.equals("SERVING SIZE")){
                sSize = sc.nextInt();
            }
        }

        sc.close();//scanner closed
    }//servingReader

    static ArrayList<String> ingrList = new ArrayList<>();//ArrayList for ingredients created

    static String scan;

    /**
     * Reads recipe and adds ingredients section to list
     */
    public static void ingrReader() throws Exception{

        //recipe read
        File recipe = new File("/home/runner/recipe.txt");
        Scanner sc = new Scanner(recipe);

        //loop to find ingredients section or recipe
        while(sc.hasNextLine()){
            String s = sc.nextLine().toUpperCase();
            //if scanner finds header INGREDIENTS, section added to ingrList
            if(s.equals("INGREDIENTS")){
                while(sc.hasNextLine()){
                    int i = 0;
                    scan = sc.nextLine();
                    ingrList.add(i, scan);
                    i+= 1;
                    //if nothing is found, breaks
                    if(scan.equals("")){
                        break;
                    }
                }
            }
        }
        sc.close();//scanner closed

        Collections.reverse(ingrList);//reverse method reverses order of elements in ingrList

        int ingr1 = ingrList.size() - 1;
        ingrList.remove(ingr1);

    }//ingrReader

    static ArrayList<Float> ingrSeperatorList = new ArrayList<Float>();//ArrayList for seperated ingredients created

    /**
     * Seperates ingredient quantitys from ingredints list and adds to seperated list
     */
    public static void ingrSeperator(){

        float ingr2 = 0;

        for(int i = 0; i <ingrList.size(); i++){
            String split [] = ingrList.get(i).split(" ");
            ingr2 =  Float.parseFloat(split[0]);
            ingrSeperatorList.add(ingr2);

        }
    }//end ingrSeperator


    /**
     * Gets serving size input from user and then adjusts seperated ingredinets accordingly
     */
    public static void divide() throws Exception{
        Scanner sc = new Scanner(System.in);

        System.out.print("Enter your serving size: ");//serving size enetered
        int servingSize = sc.nextInt();

        for(int i=0;i<ingrSeperatorList.size();i++){
            ingrSeperatorList.set(i,ingrSeperatorList.get(i)*servingSize);//origanal quantiys multiplyed by new serving size
        }

        for(int i=0;i<ingrSeperatorList.size();i++){
            ingrSeperatorList.set(i,ingrSeperatorList.get(i)/4);//multiplyed quantitys now didvided by origanal serving size 4
        }
        sc.close();//scanner closed
    }//end divide

Problem starts in my converter method:

    /**
     * Asks user for choice of units and converts arraylists accorrdingly
     */
    public static void converter() throws Exception{
        Scanner sc = new Scanner(System.in);
/*
        System.out.print("Use imperial or metric: ");//asks user for imperial or metric
        char choice =  sc.next().charAt(0);

        //if user chooses metric
        if((choice == 'a') || (choice == 'A')){*/

        //convert tbsp to ml
        for(int i = 0; i < ingrList .size(); i++){
            //if ingrList contains tbsp replaced with ml
            if(ingrList.get(i).contains("tbsp")){
                ingrList.set(i,ingrList.get(i).replace("tbsp", "ml"));

                for(int j=0;j<ingrSeperatorList.size();j++){
                    ingrSeperatorList.add(ingrSeperatorList.get(j)*15);

                }
            }
        }

        //convert tbsp to ml
        for(int i = 0; i < ingrList .size(); i++){
            //if ingrList contains cup replaced with ml
            if(ingrList.get(i).contains("cup")){
                ingrList.set(i,ingrList.get(i).replace("cup", "ml"));

                for(int j=0;j<ingrSeperatorList.size();j++){
                    ingrSeperatorList.set(j,ingrSeperatorList.get(j)*250);
                }
            }
        }

        //convert tsp to ml
        for(int i = 0; i < ingrList .size(); i++){
            //if ingrList contains tsp replaced with ml
            if(ingrList.get(i).contains("tsp")){
                ingrList.set(i,ingrList.get(i).replace("tsp", "ml"));

                for(int j=0;j<ingrSeperatorList.size();j++){
                    ingrSeperatorList.set(j,ingrSeperatorList.get(j)*5);
                }
            }
        }

    //}
    }//end converter

    /**
     * Gets serving size input from user and then adjusts seperated ingredinets accordingly
     */
    public static void multiply() throws Exception{

        for(int j=0;j<ingrSeperatorList.size();j++){
            ingrSeperatorList.set(j,ingrSeperatorList.get(j)*250);
        }
    }//end divide
}//end main
like image 548
mrgasmaskdude Avatar asked Jul 14 '26 13:07

mrgasmaskdude


1 Answers

The problem is here, when converting from tablespoons to mililiter:

for(int j=0;j<ingrSeperatorList.size();j++){
    ingrSeperatorList.add(ingrSeperatorList.get(j)*15);

}

Notice that at every other conversion you use ingr.SeperatorList.set, not .add. .add makes your list grow larger. You're using .add while looping through the list, so whenever you use .add the list will grow larger and you'll never escape the loop (until you run out of space, that is).

like image 70
nylanderDev Avatar answered Jul 18 '26 18:07

nylanderDev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!