CSC402 Apr08

slide version

single file version

Contents

  1. 4 Uses of Classes in Java
  2. Application Program
  3. An Application Program Example
  4. A Class with Utility Methods
  5. A Class with Utility Methods Example
  6. Application using Stats Utility Class
  7. A Class Defining a Type
  8. Example Class Type I
  9. Application using the Point2D class type
  10. Example Class Type II
  11. Application using the StopWatch class type
  12. Summary: Creating Classes of type I and II
  13. Summary: Applications
  14. Passing Objects as Parameters
  15. Instance Methods Inherited by all Classes
  16. More Recursive and Iterative Examples with arrays
  17. String Member Methods
  18. String Example
  19. Homework
  20. Simple Input with Scanner
  21. If Statements: Example 1
  22. Comparing instances of Class types
  23. If Statement: Example 2
  24. Comparing Strings: Example
  25. If statement: Example 2
  26. Formated printing of Strings
  27. If statement Example 3
  28. Example 3 (cont.)
  29. Read input from standard input
  30. Scanner: Input with a sentinel
  31. Sentinel Example (cont.)
  32. Reading Input without a Sentinel
  33. Example Reading Input without a Sentinel
  34. Reading Input From a File
  35. Creating a Scanner associated with a File
  36. Scanner Input from a File:
  37. Reading from a File (cont.)
  38. Comments on using hasNextInt
  39. Scanner: Reading whole lines
  40. Random Class
  41. For Loop Example
  42. For Loop Example (cont.)

4 Uses of Classes in Java[1] [top]

The Java class unit is used in Java for several different purposes:

Application Program[2] [top]

An Application Program Example[3] [top]

An application class must have a main method in order to be executable.

/**
 * Application class that prompts for an input string, 
 * converts the string to upper case and prints the 
 * converted string.
 * @author glancast
 */
public class StringApp
{
    /**
     * The main program of this application
     * @param args - command line arguments (not used)
     */
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        String line;

        greeting();

        System.out.print("Enter an input line: ");
        line = in.nextLine();
        line = line.toUpperCase();
        System.out.printf("\nHere is your input converted to upper case:\n");
        System.out.println(line);
    }  

    /** 
     * Prints an introductory message to explain
     * what input this application expects and what it does.
     */
    public static void greeting()
    {
        String msg = 
            "This program will read an input line, convert it\n" +
            "to upper case, and print the converted string.";

        System.out.println(msg);
    }

}

A Class with Utility Methods[4] [top]

A Class with Utility Methods Example[5] [top]


public class Stats {
    
    /**
     * Returns the maximum of an int array.
     * @param a
     */
    public static int maximum(int[] a)
    {
        int max = Integer.MIN_VALUE;
        for(int i = 0; i < a.length; i++) {
            if ( a[i] > max ) {
                max = a[i];
            }
        }
        return max;
    }
    
    /**
     * Returns the mean (average) of values in an integer array
     * @param a - the array
     * @return the mean value of the array members
     */
    public static double mean(int[] a)
    {
        double sum = 0.0;
        for(int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        return sum / a.length;
    }
}

Application using Stats Utility Class[6] [top]



public class StatsApp
{
  
  public static void main(String[] args)
  {
    double[] a = new double[] {86.0, 91.5, 88.0, 93.0, 94.0};

    double max = Stats.maximum(a);
    double avg = Stats.mean(a);
    System.out.printf("max = %.2f, mean = %.2f\n", max, avg);
  }

}

A Class Defining a Type[7] [top]

A type defines both data and operations on that data.

A Java class can be used to define a new type.

Variables can then be defined of that class type.

Each variable can have its own instance value of the class type.

Example Class Type I[8] [top]

A graphical application draws points. A class defines a "point" type allows defining point variables and creating "point" instances.


public class Point2D 
{

	private final double x;    // x coordinate
	private final double y;    // y coordinate

	// Constructor: initialize the (x,y) members of a new point
	public Point2D(final double x, final double y) {
		this.x = x;
		this.y = y;
	}

	public double x() { return x; }
	public double y() { return y; }

	public double distanceTo(final Point2D that) {
		final double dx = this.x - that.x;
		final double dy = this.y - that.y;
		return Math.sqrt(dx*dx + dy*dy);
	}

	public boolean equals(final Object other) {
		if (other == this) return true;
		if (other instanceof Point2D) {
		  Point2D that = (Point2D) other;
		  return this.x == that.x && this.y == that.y;
		} else {
		  return false;
		}
	}

	public int hashCode() {
		return 31 * x + y;
	}

	public String toString() {
		return "(" + x + ", " + y + ")";
	}

	// plot using StdDraw
	public void draw() {
		StdDraw.point(x, y);
	}

	// draw line from this point p to q using StdDraw
	public void drawTo(final Point2D that) {
		StdDraw.line(this.x, this.y, that.x, that.y);
	}
}

Application using the Point2D class type[9] [top]


public class Point2DApp
{
  
  public static void main(String[] args)
  {
    Point2D[] pts = new Point2D[50];

    for(int i = 0; i < 50; i++) {
      pts[i] = new Point2D(Math.random(), Math.random());
      pts[i].draw();
    }
  }
}

Example Class Type II[10] [top]

Stopwatch is a class that might not represent an concrete object in a problem application, but is used to measure timing and performance of the application.


public class StopWatch {

	private final long start;

	/**
	 * Constructor to initialize the data member of a new stopwatch instance.
	 */
	public StopWatch() {
		reset();
	}

        public void reset() {
                start = System.currentTimeMillis();
        }

	/**
	 * Return elapsed time (in seconds) since this instance was created.
	 */
	public double elapsedTime() {
		final long now = System.currentTimeMillis();
		return (now - start) / 1000.0;
	}

}

Application using the StopWatch class type[11] [top]


import java.util.Random;
import java.util.Scanner;

public class RandomApp 
{
  public static void main(String[] args) {
    int n;
    int[] a;
    Scanner in = new Scanner(System.in);
    StopWatch sw = new StopWatch();

    System.out.print("How many random integers? ");
    n = in.nextInt();
    a = new int[n];

    Random r = new Random();
    sw.reset();
    for(int i = 0; i < a.length; i++) {
	a[i] = r.nextInt(100);
    }
    double tm = sw.elapsedTime();
    System.out.printf("Time to initialize array of %d random integers: %f (msec)\n", 
                         n, tm);

    sw.reset();
    double m = Stats.mean(a);
    double sd = Stats.stddev(a);
    tm = sw.elapsedTime();

    System.out.printf("For %d random values: mean = %f, stddev = %f\n", n, m, sd);
    System.out.printf("Elapsed time to calculate mean and stddev: %f (msec)\n", tm);
  }
}

Summary: Creating Classes of type I and II[12] [top]

Classes of type I and II both define types which can be used to declare variables and to create instances of the type.

The steps to creating such a class typically consist of defining at least the following members of the class:

  1. Add private instance data members
  2. Add public constructor(s)
  3. Add public instance methods

The public instance methods can access the non static data members.

A class can also have static data members and static methods, but static methods can only access static data members of the class, not the instance data members.

Summary: Applications[13] [top]

Applications have a main method and can use public static methods of utility classes as well as instance methods of type I or type II classes.

Calling the static method random() in the utility Math class:

      double d = Math.random(); // Math is the class name
                                // random is a static method
    

Calling the reset() instance method of the StopWatch class:

      StopWatch c = new StopWatch(); // Must create an instance!

      c.reset();  // c is an instance of the StopWatch class
                  // reset is an instance method
    

Passing Objects as Parameters[14] [top]

Passing a class type variable is like assignment to the formal parameter. That is, what is copied is the reference so no copy of the value is made.

So any changes using the parameter will change the original object.

Instance Methods Inherited by all Classes[15] [top]

  1. public String toString()
  2. public boolean equals(Object other)
  3. public int hashCode()

The x.toString() method is used by System.out.println(x) for any class type variable x.

Test for equality for basic types use the == operator.

Test for equality for class types must use the 'equals' method, not the == operator.

Several Java builtin data structure classes make use of the hashCode method.

More Recursive and Iterative Examples with arrays[16] [top]

Recursive and Iterative versions of these static utility methods

  1. contains
  2. count
  3. reverse
  4. rank

String Member Methods[17] [top]

The String class has many instance methods including:

  1. public String substring(int beginIndex)
  2. public String substring(int beginIndex, int endIndex)
  3. public int length()
  4. public int indexOf(String s)
  5. public int indexOf(String s, int beginIndex)

String Example[18] [top]


public class StringEx {

  /**
   * @param args
   */
  public static void main(String[] args) {
    String date = "04/09/2013";

    int startpos = 0;
    int endpos = date.indexOf("/");
    String monthStr = date.substring(startpos, endpos);

    startpos = endpos + 1;
    endpos = date.indexOf("/", startpos);
    String dayStr = date.substring(startpos, endpos);

    startpos = endpos + 1;		
    String yearStr = date.substring(startpos);

    System.out.printf("m = %s, d = %s, y = %s\n", monthStr, dayStr, yearStr);

  }

}

Output:

m = 04, d = 09, y = 2013
      

Homework[19] [top]

Details to follow for problems

      1.2.1
      1.2.6
      1.2.7
      1.2.9
      1.2.16
    

Simple Input with Scanner[20] [top]

    1   import java.util.Scanner;
    2   
    3   /**
    4    * Description: Finds the maximum of two input integers.
    5    * 
    6    * @author glancast
    7    * 
    8    */
    9   public class Max2 {
   10   
   11     public static void main(String[] args) {
   12       int n, m;
   13       int max;
   14       Scanner input = new Scanner(System.in);
   15   
   16       System.out.println("This program computes the maximum of two input integers");
   17       System.out.printf("\nFirst integer: ");
   18       n = input.nextInt();
   19       System.out.printf("\nSecond integer: ");
   20       m = input.nextInt();
            ...
          }
        }

If Statements: Example 1[21] [top]

    1   
    2   import java.util.Scanner;
    3   
    4   /**
    5    * Description: Finds the maximum of two input integers.
    6    * 
    7    * @author glancast
    8    * 
    9    */
   10   public class Max2 {
   11   
   12     public static void main(String[] args) {
   13       int n, m;
   14       int max;
   15       Scanner in = new Scanner(System.in);
   16   
   17       System.out.println("This program computes the maximum of two input integers");
   18       System.out.print("\nFirst integer: ");
   19       n = in.nextInt();
   20       System.out.print("\nSecond integer: ");
   21       m = in.nextInt();
   22   
   23    if (n < m) {
   24         max = m;
   25       } else {
   26         max = n;
   27       }
   28       System.out.printf("The larger of %d and %d is %d\n", n, m, max);
   29   
   30     }
   31   
   32   }

Comparing instances of Class types[22] [top]

The usual comparison operators: ==, <, <=, >=, != used to compare basic numeric types would compare addresses if used for Class types.

Every class type has a method for equality testing:

        public boolean equals(Object x)
      

For some class types, the idea of an ordering makes no sense. E.g., what would it mean for one Scanner instance to be less than another Scanner instance.

So the operators <, <=, >, >= only make sense for class with an ordering.

For every class type for which there is a natural ordering, the class will have a method:

public int compareTo(Object x)  
      

For example, strings are ordered in the usual alphabetic (lexicographic) ordering:

So the String class has the compareTo method in addition to the equals method.

If Statement: Example 2[23] [top]

To compare Strings or any class type, use the compareTo method.

Comparing Strings: Example[24] [top]

        String s1 = "cat";
        String s2 = "car";
        String s3 = "catch";

        s1.compareTo(s2) is > 0  s1 comes after s2
        s1.compareTo(s3) is < 0  s1 comes before s3
        s1.compareTo("cat") is 0    s1 is equal to "cat"
        s1.equals(s2) is false
        s1.equals(s1) is true
        s1.equals("cat") is true
      

If statement: Example 2[25] [top]

Find the largest of three input strings. That is, the string that comes last in the natural ordering of strings.

    1   public class Max3 {
    2   
    3    
    4     public static void main(String[] args) {
    5       String s1, s2, s3;
    6       String max;
    7       Scanner input = new Scanner(System.in);
    8   
    9       System.out.println("This program computes the smallest of three input strings");
   10       System.out.println("That is, it prints the string that comes last in the usual " +
   11           "ordering of strings.");
   12       System.out.println();
   13       
   14       System.out.printf("\nFirst string: ");
   15       s1 = input.next();
   16       System.out.printf("\nSecond string: ");
   17       s2 = input.next();
   18       System.out.printf("\nThird string: ");
   19       s3 = input.next();
   20       
   21       max = s1;
   22       if ( s2.compareTo(max) > 0  ) {
   23         max = s2;
   24       }
   25       if (s3.compareTo(max) > 0 ) {
   26         max = s3;
   27       }
   28       ...
   29       
   30     }
   31   }

Formated printing of Strings[26] [top]

    1   public class Max3 {
    2   
    3    
    4     public static void main(String[] args) {
    5       String s1, s2, s3;
    6       String max;
    7       Scanner input = new Scanner(System.in);
    8       ....
    9       max = s1;
   10       if ( s2.compareTo(max) > 0  ) {
   11         max = s2;
   12       }
   13       if (s3.compareTo(max) > 0 ) {
   14         max = s3;
   15       }
   16       System.out.printf("For strings '%s', '%s', and '%s', %s comes last in the usual ordering.",
   17           s1, s2, s3, max);
   18       
   19     }
   20   }

If statement Example 3[27] [top]

Write a method String letterGrade(int score) that returns the letter grade for a test.

The letter grade should be computed from the score by

   A: >= 94
   B: >= 85
   C: >= 76
   D: >= 67
   F: >= 0
      

Example 3 (cont.)[28] [top]

    1   public class GradeComp {
    2   
    3     public static String letterGrade(int score) {
    4       String grade;
    5       if ( score >= 94 ) {
    6         grade = "A";
    7       } else if ( score >= 85 ) {
    8         grade = "B";
    9       } else if ( score >= 76 ) {
   10         grade = "C";
   11       } else if ( score >= 67 ) {
   12         grade = "D";
   13       } else {
   14         grade = "F";
   15       }
   16       return grade;
   17     }
   18     
   19     public static void main(String[] args) {
   20       int score;
   21       String grade;
   22       Scanner input = new Scanner(System.in);
   23       
   24       System.out.print("Enter a test score: ");
   25       score = input.nextInt();
   26       
   27       grade = letterGrade(score);
   28       
   29       System.out.printf("For numeric score %d, the grade is %s", score, grade);
   30     }
   31   }

Read input from standard input[29] [top]

The Scanner class has methods hasNext(), hasNextInt(), etc. that return a boolean depending on whether the next input of the indicated type is on the input.

For input from standard input (the keyboard), hasNext must wait for the user to type in some value. So it simply doesn't return until the user does so.

Instead of using the hasNext() method, the programmer can choose a special value (e.g. -1) for the user to enter to mean no more input.

The special value will only indicate the end of input and will not be processed otherwise.

Such a special value is called a "sentinel".

Scanner: Input with a sentinel[30] [top]

Read non-negative integers from standard input until the user enters a value of -1, the sentinel to signal end of input.

Count the values read (not including the sentinel) and print the count and the maximum value read.

Sentinel Example (cont.)[31] [top]

    1   import java.util.Scanner;
    2   
    3   public class SentinelInput {
    4   
    5     public static void main(String[] args) {
    6       
    7       Scanner input = new Scanner(System.in);
    8       int max = 0, n;
    9       final int SENTINEL = -1;
   10       System.out.println("This program will read integers from standard input and print " +
   11           " number of values read and the largest value.");
   12       System.out.printf("\nTo signal end of input, enter a sentinel value of -1\n\n");
   13       
   14       int count = 0;
   15       System.out.print("input value> ");
   16       n = input.nextInt();
   17       max = n;
   18       while( n != SENTINEL ) {
   19         count++;
   20         if ( n > max ) {
   21           max = n;
   22         }
   22a        n = input.nextInt();
   23       }
   24       System.out.printf("There were %d values read.\n", count);
   25       if ( count > 0 ) {
   26         System.out.printf("The maximum value read was %d\n", max);
   27       }
   28          
   29     }
   30   }

Reading Input without a Sentinel[32] [top]

An appropriate sentinel value may not exist.

If the previous program processed all integers - negative as well as non-negative, there are no integer values left to use as a sentinel.

The hasNext family of Scanner methods can be used to detect end of input.

Note that hasNextInt() will return false at end of input or if the next input is doesn't represent an int.

The hasNext methods return false instead of throwing an exception if the input is not what is expected.

Example Reading Input without a Sentinel[33] [top]

    1   import java.util.Scanner;
    2   
    3   public class SentinelInput {
    4   
    5     public static void main(String[] args) {
    6       
    7       Scanner input = new Scanner(System.in);
    8       int max = 0, n;
   10       System.out.println("This program will read integers from standard input and print " +
   11           " number of values read and the largest value.");
   12       System.out.printf("\nTo signal end of input, type ctrl-z (or ctrl-d)\n\n");
   13       
   14       int count = 0;
   15       System.out.print("input value> ");
   16       while( input.hasNextInt() ) {
   17         n = input.nextInt();
   18         if ( count == 0 ) {
   19            max = n;
   20         } else {
   21           if ( n > max ) {
   22             max = n;
   23           }
   24         }
   25         count++;
   26       }
   27       System.out.printf("There were %d values read.\n", count);
   28       if ( count > 0 ) {
   29         System.out.printf("The maximum value read was %d\n", max);
   30       }
   31          
   32     }
   33   }

    

Reading Input From a File[34] [top]

Almost the same code can be used to read integers from a file.

The only difference is in the creation of the Scanner.

After that, the code is the same.

Creating a Scanner associated with a File[35] [top]

import java.util.Scanner;

    1   public static void main(String[] args) {
    2       String fileName;
    3       Scanner input = new Scanner(System.in);
    4       Scanner infile = null;
    5       int max = 0, n;
    6       
    7       System.out.println("This program will read integers (negative, non-negative) and print the largest value.");

   10       fileName = input.next();
   11       
   12       // Try to create a Scanner for the file name entered
   13       try {
   14         infile = new Scanner(new File(fileName));
   15       } catch(FileNotFoundException e) {
   16         System.out.printf("Unable to open input file %s\n", fileName);
   17         System.exit(1);
   18       }
   19       ...
   20   }

Scanner Input from a File: [36] [top]

To count and find the maximum of integers in an input file, we need to first set up the Scanner.

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

    1   public static void main(String[] args) {
    2       String fileName;
    3       Scanner input = new Scanner(System.in);
    4       Scanner infile = null;
    5       int max = 0, n;
    6       
    7       System.out.println("This program will read integers from a file and print the largest value.");
    8       System.out.printf("\nEnter the input file name: ");
    9       
   10       fileName = input.next();
   11       
   12       // Try to create a Scanner for the file name entered
   13       try {
   14         infile = new Scanner(new File(fileName));
   15       } catch(FileNotFoundException e) {
   16         System.out.printf("Unable to open input file %s\n", fileName);
   17         System.exit(1);
   18       }
   19       ...
   20   }

Reading from a File (cont.)[37] [top]

Once a Scanner is created for a file of integers, the Scanner hasNextInt() method can be used as the while loop test for end of input.

The initialization of the max should be the first value read (if the file is not empty). This changes the code a bit from the sentinel example:

    1   public class SimpleFileInput {
    2   
    3     /**
    4      * @param args
    5      */
    6     public static void main(String[] args) {
    7       String fileName;
    8       Scanner input = new Scanner(System.in);
    9       Scanner infile = null;
   10       int max = 0, n;
   11       
   12       System.out.println("This program will read integers from a file and print the largest value.");
   13       System.out.printf("\nEnter the input file name: ");
            ...
            /* code to create a Scanner for infile goes here, but is not shown */
            ...
   24       int count = 0;
   25       while(infile.hasNextInt()) {
   26         if (count == 0) {
   27           max = infile.nextInt();
   28         } else {
   29           n = infile.nextInt();
   30           if ( n > max ) {
   31             max = n;
   32           }
   33         }
   34         count++;
   35       }
   36       System.out.printf("There were %d values read from input file %s.\n", count, fileName);
   37       if ( count > 0 ) {
   38         System.out.printf("The maximum value read was %d\n", max);
   39       }
   40          
   41     }
   42   }

Comments on using hasNextInt[38] [top]

What happens if the input file has some integers but then has a typo such as u6 instead of 86?

What happens to the example with the sentinel example?

Scanner: Reading whole lines[39] [top]

Since the Scanner next() method stops as soon as it encounters whitespace (a blank, tab, newline, carriage return) it can't be used directly to read a line that contains blanks such as a person's full name.

The Scanner class has a nextLine() method that reads the entire line. It returns the input line as a single String. The returned string does not include the end of line character.

Random Class[40] [top]

Instead of manually creating a text file of integers for testing, the Random class has a method to create pseudo random sequences of integers or doubles and the other numeric types. It also lets you restrict the range of the numbers generated; e.g. you may only want values in the range 0 to 100 in one case or 2 to 12 in another case (two dice).

        Random r = new Random();
        int x;

        x = r.nextInt(101); // x will be a random int with 0 <= x < 101
        y = r.nextInt(11);  // y will be a random int with 0 <= y < 10
      

For Loop Example[41] [top]

Use the Random class and a for loop to create exactly 1000 values in the range 1 to 100 (not 0 to 99) and count the number of values <= 50. It should be about 500 if the random numbers are distributed uniformly in the range 1 to 100.

For Loop Example (cont.)[42] [top]

    1   import java.util.Random;
    2   
    3   public class RandomTester {
    4   
    5     public static void main(String[] args) {
    6       Random r = new Random();
    7       final int NGEN = 1000;
    8       final int TOPVALUE = 100;
    9       int count = 0;
   10       int n;
   11   
   12       // Generate NGEN random numbers, each in the range 1 to TOPVALUE 
   13       for(int i = 0; i < NGEN; i++ ) {
   14         n = r.nextInt(TOPVALUE) + 1;
   15         if ( n <= TOPVALUE/2 ) {
   16           count++;
   17         }
   18       }
   19       System.out.printf("Of %d random numbers, each in the range 1 to %d\n" +
   20           "%d were less than or equal to %d", NGEN, TOPVALUE, count, TOPVALUE/2);
   21     }
   22   
   23   }