The Java class unit is used in Java for several different
purposes:
The class has the main method for an application program
The class is a container for a collection of utility methods
The class defines a type that represents concrete or abstract objects in some
application/problem context.
The class defines a type that doesn't correspond directly to the kind of objects in
an application/problem.
However, such a class may be useful in applications - for
example, to store application objects or to help process
application objects.
The class must contain a main method
The main method is static
The class may contain other static methods that can be
called by main.
-
The class may contain static data members. These are shared
by all methods in the class.
-
The main method (and other methods in the class) may create
and use local variables of basic and/or class types.
-
An application class typically does not define a new type.
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);
}
}
-
Contains a collection of utility methods which are all
static.
-
The static member methods typically operate only on data
passed as parameters, so there are typically no data members
in the class.
-
The class typically contains no data members. But if it
does, these are static data members.
-
Static methods can only access static data
members of a class (provided there are any such members).
-
A utility class with static methods (with or without static
data members) does not define a
new type.
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;
}
}
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 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.
-
The class has data members that are not static. These
are called instance members.
-
Variables can be declared of this class type.
-
Values can be created and assigned to such variables. Each
variable will have its own separate set of instance data
members.
So unlike static data members of a class, instance
members are not shared.
-
The methods of a class that defines a type are not
static. These are called instance methods.
An instance method operates on the instance data of the instance
used to call it.
Instance data members of the class are accessible to each of the
instance methods (but not to any static methods).
-
Typically such a class is not used as an application and so
doesn't need a main method.
Instead, some application class will use a class like
this. For example, an application class may declare,
create and use an instance of this class type.
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);
}
}
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();
}
}
}
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;
}
}
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);
}
}
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:
- Add private instance data members
- Add public constructor(s)
- 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.
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 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.
- public String toString()
- public boolean equals(Object
other)
- 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.
Recursive and Iterative versions of these static utility methods
- contains
- count
- reverse
- rank
The String class has many instance methods including:
- public String substring(int beginIndex)
- public String substring(int beginIndex,
int endIndex)
- public int length()
- public int indexOf(String s)
- public int indexOf(String s, int beginIndex)
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
Details to follow for problems
1.2.1
1.2.6
1.2.7
1.2.9
1.2.16
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();
...
}
}
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 }
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:
- "car" comes before "cat"
- "cat" comes before "catch"
So the String class has the compareTo method in
addition to the equals method.
To compare Strings or any class type, use the
compareTo method.
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
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 }
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 }
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
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 }
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".
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.
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 }
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.
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 }
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.
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 }
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 }
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 }
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?
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.
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
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.
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 }