I need to create a program that accepts input from a file. I need to ask the user to enter two(2) variables, the interest rate and months for the loan. I then calculate the monthly payment, output the original input from the file along with the number of months on the loan and the monthly payment.
I am having issues with getting the numbers in the array to int's so that I can calculate them. I have tried a few things, but cannot get this to do what I want. After reading through some other questions I was able to find how to convert the array to an int and get the sum so I have included this in the code. I know how to do the calculations after I get the array of "item" to an int. I am only looking for assistance on the part of converting item[1] to an array that I can use to calculate the sum of the items. I have included comments in the code that might better show what I'm looking for.
This is what the input file looks like:
Driver 425
Putter 200
Wedges 450
Hybrid 175
This is my code:
import java.io.*;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.*;
public class Assignment3t {
public static void main(String[] args) {
File inputFile = new File("Project3.txt");
File outputFile = new File("Project3Output.txt");
Scanner scanner = new Scanner(System.in);
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
System.out.print("Enter the interest rate: ");
float interestRate = scanner.nextFloat();
System.out.print("Enter months for the loan: ");
int loanMonths = scanner.nextInt();
try {
bufferedReader = new BufferedReader(new FileReader(inputFile));
bufferedWriter = new BufferedWriter(new FileWriter(outputFile));
String line;
while ((line = bufferedReader.readLine()) !=null) {
String[] item = line.split("\\s ");//create an array. This is the part I cant figure out. It creates the array, but I cant figure out how to get this data to "results" below.
int[] results = Stream.of(item).mapToInt(Integer::parseInt).toArray(); //converts the string array to an int array.
int sum = Arrays.stream(results).sum(); //calculates the sum of the array after its converted to an int to use in the monthly payment calculation.
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.write("Number of months of the loan: " String.valueOf(loanMonths));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
CodePudding user response:
Your input consists of alternating numeric and non-numeric data. And after splitting the line on white spaces with split("\\s ")
you are trying all the strings into int
. That will inevitably lead to NumberFormatException
at runtime.
To avoid that you need to add a filter()
to the stream to ensure that only strings that are comprised of digits will be parsed.
And since you are using int[] results
only as a source of the second stream that calculates the sum
then you should get rid of redundancy. There's no need to create a second stream and allocate in memory unused array.
Another mistake is that the scope of the variable sum
is limited to the while
loop. And according to your example of the input, a line will contain only at most only one digit. That doesn't make much sense and I think that wasn't your intention.
Here is one of the ways how to resolve these issues:
int sum = 0;
try(Stream<String> lines = Files.lines(inputFile.toPath())) {
sum = getSum(lines);
} catch (IOException e) {
e.printStackTrace();
}
Note that try-with-resources is a preferred way to deal with resources that implement AutoCloseable
. When execution of the try
block finishes (normally or abruptly) all resources will be closed.
Logic for calculating the sum:
public static int getSum(Stream<String> lines) {
return lines.flatMap(line -> Stream.of(line.split("\\s ")))
.filter(str -> str.matches("\\d "))
.mapToInt(Integer::parseInt)
.sum();
}
That basically the answer to the question:
Convert String array to an Int array and total it
To fix other parts of your code you have to have a clear understanding of what you are trying to achieve. There is a lot of actions packed together in this code, you need to split it into separate methods each with its own responsibility.
The code for writing to the outputFile
seems to be unrelated to the process of calculating the sum. Basically, you are creating a copy of the inputFile
with only one additional line: "Number of months of the loan: " String.valueOf(loanMonths)
.
If you insist these actions must be done at the same time, for instance, the inputFile
could be large, then it might be done like this:
try(BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.newLine();
if (!line.isBlank()) {
sum = Integer.parseInt(line.split("\\s ")[1]);
}
}
writer.write("Number of months of the loan: " String.valueOf(loanMonths));
} catch (IOException e) {
e.printStackTrace();
}
Note that in this case, Java 8 streams are not needed because a line can contain only a single value and there's nothing to process with a stream.