【发布时间】:2020-03-29 19:14:04
【问题描述】:
上下文
我有一项任务要求我从文本文件中读取食谱并操作测量单位和成分数量等内容。我已经设法将配方分成三个数组列表,现在必须开始将英制单位转换为公制。但是当我尝试乘以和转换相应的单位时,我得到了 Java 堆空间错误。我在网上查看了如何解决此问题,并意识到这可能与数组列表泄漏内存或使用过多空间有关。问题是我不知道这可能发生在哪里,并且已经尝试使用浮点列表或整数列表而不是双精度,但它仍然没有工作,因为我仍然需要使用小数。我知道字符串转换为 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
【问题讨论】:
-
与您的问题无关,但观察和建议:您的代码不是面向对象的。对于这样的作业,我希望看到像
Recipe、Ingredient和Units这样的课程共同解决问题。如果您可以分离职责,它将使您的代码更易于阅读和理解。如果您无法做到这一点,我建议您为变量使用更清晰的名称,例如ingrList -> ingredients,sc -> scanner,ingrSeparatorList -> quantities。当您可以轻松阅读代码时,您会发现调试起来会容易得多。 -
感谢您的反馈。在我的下一个任务中,我肯定会考虑到这一点,因为我现在意识到调试这么多事情是一件很痛苦的事情。
标签: java arraylist memory-management file-io memory-leaks