Formatting
Numeric OutputSeveral of the programs this far have decimals in the output, which can appear with varied numbers of decimal places. One way to improve the look of a program is to use the NumberFormat class, which is found in java.text. It may seem strange to find the tools for formatting numbers in a "text" section but all values shown on screen are indeed translated to text format for output otherwise they could not be read.
The NumberFormat class allows you to format objects as regular numbers, as currency, and as percent. In the following sample program, objects of all three types are created. The setMaximumFractionDigits method is also used to round numbers to 2 decimals. The numbers are properly rounded, not truncated.
/*The TestNumberFormat program
*Programmed by: Mr. J. Augustine, March 2004
*This program creates 3 NumberFormat objects to demonstrate formatting output
*as decimals, currency, and percent.*/
import java.text.*;
public class TestNumberFormat{
public static void main (String [ ] args){
//This program will be written entirely in the main method
//Get the local format and specify two decimals. The
//resulting number will be rounded.
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);
//percent format
NumberFormat nfPercent = NumberFormat.getPercentInstance();
//currency format
NumberFormat nfCurrency = NumberFormat.getCurrencyInstance();
double num = .57854231;
System.out.println(nf.format(num));
System.out.println(nfPercent.format(num));
System.out.println(nfCurrency.format(num));
}//end main method
}//end class
The while loop repeats an instruction or block of instructions until a condition is met. The generic form of a while loop is:
while (**condition**) {
**instructions to repeat**
}
In this sample, a while loop is used to calculate interest and the number of years it will take for money to double. The condition, while (amount < target), continues the loop until the amount is equal or greater than the target, which is twice the original amount.
/*The While Sample Program
*Programmed by: Mr. J. Augustine, March 2004
*This class uses a while loop to determine the time to double
*a given amount of money at a given rate.*/
public class WhileSample1 {
public static void main (String [ ] args){
//This sample program will be written entirely in the main method
double rate, amount, targetAmount;
int yearCounter = 0;
System.out.print("Enter the amount to be invested: ");
amount = ReadLib.readDouble();
//After the amount is input the target or double the money is calculated.
targetAmount = amount * 2;
System.out.print("Enter the annual interest rate: ");
rate=ReadLib.readDouble();
//The loop continues to execute until the amount is no less than the
//target amount.
while (amount < targetAmount) {
amount = amount * (1 + rate);
//This could also be written amount *= (1 + rate)
yearCounter++;
}//end while loop
//Output to the screen:
System.out.println("It will take " + yearCounter +
" years for the money to double.");
}//end the main method
}//end class
Using
a While Loop to Error-Trap InputsThe following program uses a while loop to error-trap user inputs. The program accepts a number from 1 to 1000 and displays the square root of the number. If a number outside the range is input, the program will not calculate the square root, instead it will ask the user to enter the input number again.
/*The While Sample 2 Program
*Programmed by Mr. J. Augustine, March 2004
*This program demonstrates the use of a while loop. It is used to keep
*asking the user for input until a number in the correct range is input.
*The program requests an integer between 1 and 1000 and then calculates
*and displays the square root.*/
import java.text.*;
public class WhileSample2 {
public static void main (String [ ] args) {
//For the purposes of this sample, the entire program is written in the
//main method.
int number = 0;
double squareRoot;
//Use NumberFormat from java.text.*; to format the output
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
while (number < 1 || number > 1000) {
//The while loop ensures correct input
System.out.print("Enter a number from 1 to 1,000: ");
number = ReadLib.readInt();
if (number >=1 && number <=1000){
//The if structure calculates the square root ONLY if the
//number is in the correct range.
//Use the Math class in java.lang to calculate the square root
squareRoot = Math.sqrt(number);
//Output the results without formatting
System.out.println("The unformatted square root of " + number +
" is " + squareRoot);
//Output the results with formatting
System.out.println("The formatted square root of " + number +
" is " + nf.format(squareRoot));
}//end if structure
else {
System.out.println("Invalid input, the number must be between 1 and 1000.");
}//end else structure
}//end while loop
}//end main method
}//end class
While
Loops with a SentinelThe following program uses a while loop and a sentinel to stop the loop. Notice the difference in program logic for sentinel-controlled repetition compared with the counter-controlled repetition. In counter controlled repetition, we read a value from either the user or the program during each pass of the while structure for the specified number of passes. In sentinel-controlled repetition, we read one value before the program reaches the while structure. This value is used to determine if the program's flow of control should enter the body of the while structure. If the while structure condition is false (i.e. the user already typed the sentinel), the body of the while structure does not execute (no grades were entered). If, on the other hand, the condition is true, the body begins execution and the value entered by the user is processed (added to the total in this example). After the value is processed, the next value is input from the user before the end of the while structure's body. As the closing right brace ( } ) of the body is reached execution continues with the next test of the while structure condition using the new value just entered by the user to determine if the while structure's body should execute again. Notice that the next value is always input from the user immediately before the while structure condition is evaluated. This allows us to determine if the value just entered by the user is the sentinel value before that value is processed. (i.e. added to the total). If the value entered is the sentinel value, the while structure terminates and the value is not added to the total.
/*The While Sample 3 Program
*Programmed by Mr. J. Augustine, March 2004
*This program demonstrates the use of a while loop with sentinel
*controlled repetition. The program allows a user to enter a
*a series of marks and then use a sentinel to exit. The program
*then outputs the class average to two decimal points.*/
import javax.swing.JOptionPane;
import java.text.DecimalFormat;
public class WhileSample3 {
public static void main (String [ ] args) {
//The entire program will be written in the main method
//for demonstration purposes.
int gradeCounter, //number of grades entered
gradeValue, //numerical grade value
total; //sum of all grades
double average; //average of all grades
String input; //grade typed in by user
//Initialization phase
total = 0; //clear total
gradeCounter = 0; //prepare value for loop
//Processing phase
//Prompt for input and read grade from user.
input = JOptionPane.showInputDialog("Enter an integer grade or enter -1 to quit: ");
//Convert grade from a String to an integer.
gradeValue = Integer.parseInt(input);
while (gradeValue !=-1) {
//The loop now allows the user to keep entering grades until finished.
//add gradeValue to total
total += gradeValue;
//add 1 to gradeCounter
gradeCounter++;
//Prompt for input and read grade from user
input = JOptionPane.showInputDialog("Enter an integer grade or enter -1 to quit: ");
//Convert grade from a String to an integer.
gradeValue = Integer.parseInt(input);
}//end while loop
//Termination phase
DecimalFormat twoDigits = new DecimalFormat ("0.00");
//The if statement will check to make sure we are not dividing by zero
if (gradeCounter !=0){
average = (double) total/gradeCounter;
//Display the average of the marks
JOptionPane.showMessageDialog(null, "The class average is " + twoDigits.format(average),
"Class Average", JOptionPane.INFORMATION_MESSAGE);
}//end if statement
else {
JOptionPane.showMessageDialog(null, "No grades were entered.", "Class Average",
JOptionPane.INFORMATION_MESSAGE);
}//end else statement
System.exit (0); //Terminate the program.
}//end main method
}//end class
The only type of loop that is needed by a programmer is a while loop, the for loop is another type of loop that is easier to use when you know how many times the loop must be repeated. A loop where the number of iterations is not known by the program is known as an indeterminate loop. It requires a sentinel to exit the structure. A loop where the number of iterations is known at the outset is commonly referred to as a determinate loop. The most common form of a determinate loop is the for loop. The for loop begins with a counter variable that determines how many times the instructions inside the loop will be repeated. The loop in the following program begins with:
for (int i = 1; i <= 9; i++)
This means that the loop declares and gives the variable i the initial value of 1 (int i = 1). The loop continues while i is less than or equal to 9 (i <= 9) and the i is incremented by one each time through the loop. The loop would execute 9 times with the value of i being 1, 2, 3, 4, 5, 6, 7, 8, 9.
This program also introduces the concept of a constant declared with the final keyword. The declaration:
final int PAR = 36;
declares PAR as 36, the value of PAR cannot be changed in the program. By convention, upper case letters are used to show constants.
/*The For Sample 1 Program
*Programmed by Mr J. Augustine, March 2004
*This program demonstrates the use of a for loop by calculating
*the score for nine holes of golf and the difference from par.*/
import ReadLib;
public class ForSample1 {
public static void main (String [ ] args) {
//The entire program will be written in the main method
//for sake of simplicity.
final int PAR = 36;
int diffPar, strokes, totalScore = 0;
//the for loop gets the score for each hole
for (int i = 1; i <=9; i++) {
System.out.print("Enter the number of strokes for hole #" + i + ": ");
strokes = ReadLib.readInt();
totalScore += strokes;
}//end for loop
//determine difference from par
diffPar = totalScore - PAR;
System.out.println("The number of strokes you used on the circuit is "
+ totalScore);
//an if statement is used to display the appropriate message
if (diffPar < 0)
System.out.println("Your score is " + Math.abs(diffPar) + " below par." );
else if (diffPar > 0)
System.out.println("Your score is " + diffPar + " above par.");
else
System.out.println("Your score is at par.");
}//end main method
}//end of class
Nested
for LoopsJust as we saw with if statements, any type of loop can be nested. The following sample shows a simple nested for loop. See if you can predict the output before you run the program.
/*The For Sample 2 Program
*Programmed by: Mr. J. Augustine, March 2004
*This program will demonstrate the use of nested for loops. */
public class ForSample2 {
public static void main (String [ ] args) {
for (int i = 1; i <= 5; i++) { // outer loop
for (int j = 0; j <= 4; j++) {// inner loop
System.out.println("i = " + i + " j = " + j);
}//end inner for loop
}//end outer for loop
}//end main method
}//end class
Nested for loops are particularly useful when initializing 2-dimensional arrays. Remember this note for the next unit when we deal with arrays.
Human beings are the slowest part of a computer system. Even the fastest keyboarder cannot input text as quickly as a computer can read it from a file. The majority of business applications input data from a file rather than the keyboard. A text file in Java is opened with the BufferedReader class, the same class as used for keyboard input, except that it also uses the FileReader class to link to a file. The read method used is the readLine( ) method. Each line of input text is converted to integer using the Integer.parseInt ( ) method.
The assumption here is that the file is in the same folder as the class file. If the file is located somewhere else, the entire path to the file as well as the file name must be included inside the quotations marks.
/*The For Sample 3 Program
*Programmed by Mr. J. Augustine, March 2004
*This program opens a text file, reads the data of 9 numbers
*and determines the highest number in the file.*/
import java.io.*;
public class ForSample3 {
public static void main (String [ ] args) throws IOException {
//For the sake of simplicity the entire program will be written
//in the main method.
//Open the text file to read the information
BufferedReader br = new BufferedReader (new FileReader ("numbers.txt"));
//the internal name br now refers to "numbers.txt" This would require the
//entire path to the file if the file were not in the project folder.
int num;
//Integer.parseInt( ) converts a number stored as a String to an int value
//The first number is read in to give highest an initial value.
int highest = Integer.parseInt(br.readLine());
//for loop reads in the rest of the numbers
for (int i = 1; i <=9; i++) {
num = Integer.parseInt(br.readLine());
//change the value of highest each time a new highest value is found
if (num > highest)
highest = num;
}//end for loop
//the input file must be closed
br.close();
System.out.println("The highest number in the file is: " + highest);
}//end main method
}//end class
Writing
to a Text FileThe following program creates a text file of 1000 marks. Note the use of the PrintWriter and FileWriter classes to set up an output stream to the file. Copy the program and run it. You will need the marks.txt file for the lab assignment.
/*The ForSample4 Program
*Programmed by Mr. J. Augusitne, March 2004
*This program creates a 1000 item text file containing
*random marks from 30 to 100. */
import java.io.*;
public class ForSample4 {
public static void main (String [ ] args) {
//The entire program is written in the main method for
//ease of demonstration.
//The try statement is required in case there is an exception.
//The system may for some reason not be able to write to the
//file as instructed.
try {
//PrintWriter is like BufferedReader except that it is used for output
PrintWriter pw = new PrintWriter (new FileWriter ("marks.txt"));
//FileWriter is the output equivalent of FileReader
int number;
for (int i=0; i < 1000; i++){
//This for loop will generate 1000 random numbers between 30
//and 100 and output them to the screen and to a text file.
//This part generates the random numbers.
number = (int) (Math.random()*71) + 30;
//pw.println outputs to a file instead of the screen
pw.println(Integer.toString(number));
System.out.println("Mark: " + number);
}//end for loop
//Closing the file is essential for output files
pw.close();
}//end try statement
catch (IOException io) {
System.out.println("The file marks.txt could not be opened or written to. Please check
to make sure you have rights to write to this file area.");
}//end catch statement
}//end main method
}//end class