解决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, 即).
上下文
我有一项作业要求我从文本文件中读取食谱并操作内容,例如测量单位和配料数量。我设法将食谱分成三个数组列表,现在必须开始将英制单位转换为公制单位。但是,当我尝试乘以并转换相应的单位时,出现 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, 即).