解决Java heap space double Arraylist 添加新值时报错

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

上下文

我有一项作业要求我从文本文件中读取食谱并操作内容,例如测量单位和配料数量。我设法将食谱分成三个数组列表,现在必须开始将英制单位转换为公制单位。但是,当我尝试乘以并转换相应的单位时,出现 Java 堆 space 错误。我在网上查看了如何解决这个问题,并意识到它可能与数组列表泄漏内存或使用太多 space 有关。问题是我不知道这可能发生在哪里,并且已经尝试使用浮点列表或整数列表而不是双精度列表但它仍然没有用,因为我仍然需要使用小数。我知道将字符串转换为 ml 有效,但不知道相应的数字转换是否有效,将不胜感激。

代码

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

我的转换器方法开始出现问题:

    /**
     * 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

问题出在这里,当从汤匙转换为毫升时:

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

}

请注意,在其他所有转换中,您都使用 ingr.SeperatorList.set,而不是 .add.add 让您的列表变大。您在循环列表时使用 .add,因此每当您使用 .add 时,列表都会变大并且您永远无法逃脱循环(直到 运行 超出 space, 即).