Please note that everything in this set of notes is really just revision of material you have already covered in your first programming course. There is no need to bother with this set of notes if you are happy with that course, have understood the material, done well in the tests, and managed to do all the coursework and exercises on your own. These notes cover material which it is necessary to be familiar with for the Algorithms and Data Structures course, but past experience suggests some students still have difficulty with.
import java.util.*;This program has a neater appearance, because the code is broken up into several static methods. You were told previously that the important bit of code was the bit which went through the array, and the rest was just supporting input/output stuff which you needn't consider in any detail. Now the important bit is separated out into its own method called
import java.io.*;
class CountNumber2
// A program to read a list of numbers then read one number and
// count the number of times it occurs in the list.
// Code broken up into separate static methods.
{
public static void main(String[] args) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] a = readNumbers(in);
int n = readANumber(in);
int count = count(n,a);
System.out.print("The number "+n);
System.out.println(" occurs "+count+" times in the list");
System.out.println("That's all");
}
public static int[] readNumbers(BufferedReader in) throws Exception
{
System.out.println("Enter a list of numbers (all on one line):");
String line = in.readLine();
StringTokenizer toks = new StringTokenizer(line);
int[] a = new int[toks.countTokens()];
for(int i=0; i<a.length; i++)
a[i] = Integer.parseInt(toks.nextToken());
return a;
}
public static int readANumber(BufferedReader in) throws Exception
{
System.out.print("Enter a number: ");
String line = in.readLine();
int n = Integer.parseInt(line);
return n;
}
public static int count(int n,int[] a)
{
int count=0;
for(int j=0; j<a.length; j++)
if(a[j]==n)
count++;
return count;
}
}
count
. We also separated out two
bits of code which prompt for values and return them. The first,
which we have called readNumbers
, prompts for a list of
numbers and returns them stored in an array. The second, which we have
called readANumber
, prompts for a single number and
returns it.
The main
method, which is where execution of a Java
program
always starts off, consists mainly of calls to those methods
A static method can be considered a piece of code that is
parameterised.
It's slightly more complex than that in Java, but for now this will do
as an explanation. If we have a method call meth(a,b)
then we need a static method in the same class called meth
which has a header which includes meth(atype c, btype d)
.
Here atype
and btype
are in italics because they can be any types, but they must match the
type of the variables a
and b
respectively.
What happens then is that execution of the code where the call
meth(a,b)
occurs is halted. Instead the code following the
{
in the method is executed, but with c
replaced by
a
and d
replaced by b
. This
is what is meant by "parameterisation" - c
and d
are the parameters which are replaced by the arguments (a
and
b
in this case) when the method is executed.
All methods must have a return type. When a statement written
return
followed by some value, which must be of the return
type of the method, is executed, execution returns to the point where
the
method was called. You can think of the method call as being replaced
by the value that was returned. In the above example, you can see that
the return type for the method readNumbers
is int[]
,
that is, an array of integers, whereas the return type for the methods
readANumber
and coun
is int
,
that
is, a single integer.
A special return type written void
is used for methods
that
don't return anything. In this case, the method will execute until
it reaches the final closing }
, although you can use
return;
on its own to cause it to halt.
In the above code, note that as in
is just another
variable in the main
method, if you want to use it in
some other method, you have to pass it as an argument to that method.
Its type is BufferedReader
, so that has to be given to
the
parameter of the method. As a Java input/output thing, note that if
buf
is a BufferedReader
, every time you
call buf.readLine()
there is a chance you might "throw
a checked exception". That is why the methods readNumbers
and readANumber
have to have the words throws Exception
after their headers, because they
have a call to readLine()
attached to a
BufferedReader
variable inside them. Exceptions are an
aspect of Java you won't have covered yet, so don't worry about this,
it isn't important to this course.
import java.util.*;There is also a separate method called
import java.io.*;
class CountNumber3
// A program to read a list of numbers then read one number and
// count the number of times it occurs in the list.
// Code broken up into separate static methods.
// Shows use of different parameter names to arguments.
{
public static void main(String[] args) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] a = readNumbers(in);
int n = readANumber(in);
int count = count(n,a);
display(n,count);
System.out.println("That's all");
}
public static void display(int num, int c)
{
System.out.print("The number "+num);
System.out.println(" occurs "+c+" times in the list");
}
public static int[] readNumbers(BufferedReader reader) throws Exception
{
System.out.println("Enter a list of numbers (all on one line):");
String line = reader.readLine();
StringTokenizer toks = new StringTokenizer(line);
int[] a = new int[toks.countTokens()];
for(int i=0; i<a.length; i++)
a[i] = Integer.parseInt(toks.nextToken());
return a;
}
public static int readANumber(BufferedReader reader) throws Exception
{
System.out.print("Enter a number: ");
String line = reader.readLine();
int n = Integer.parseInt(line);
return n;
}
public static int count(int m,int[] b)
{
int occurrences=0;
for(int j=0; j<b.length; j++)
if(b[j]==m)
occurrences++;
return occurrences;
}
}
display
which
prints out the results of the count. This is given to illustrate a
void
-returning method.
To illustrate how this code works, consider the line in the
main
method:
int count = count(n,a);This is a call to the method whose signature is:
public static int count(int m,int[] b)In the call, the argument
n
is matched against
the parameter name m
, and the argument a
is matched against the parameter name b
. You can think of
this as executing the code for the method count
, which
is:
int occurrences=0;with
for(int j=0; j<b.length; j++)
if(b[j]==m)
occurrences++;
return occurrences;
m
replaced by n
and b
replaced by a
. However, a better way of thinking of it
is that the code is executed with m
assigned the value
of n
and b
assigned the value of a
.
That means the statement
int count = count(n,a);is equivalent to:
int m=n;Note how the value which is returned replaces the original method call.
int[] b=a;
int occurrences=0;
for(int j=0; j<b.length; j++)
if(b[j]==m)
occurrences++;
int count = occurrences;
The reason for this is that parameters can be used just like variables in the code of a method, and even be assigned new values. However, assigning them a new value does not change the value of the argument they were matched with. To demonstrate this, suppose we had the method:
int square(int m)If we had the code:
{
m=m*m;
return m;
}
int h=5;it wouldn't have the effect of changing the value of
int k=square(h);
a
.
The effect is as if:
int h=5;is executed, and not:
int m=h;
m=m*m;
int k=m;
int h=5;Note that when two arrays are assigned, for example, above we had
h=h*h;
int k=h;
int[] b=a;for passing the array
a
as an argument to a method to
match parameter b
, the effect is that b
becomes another name for the array a
. This is something
we will discuss in more detail in the course later on, since it has
quite a big practical effect on methods that deal with data structures.
void
. Here is
that method again:
public static void display(int num, int c)Many people when learning to program confuse printing a value with returning it. It is important to realise that the two are completely different. Printing a value causes something external to the program to happen: the value is displayed in some way, or left on a file. Returning a method means that it is passed around internally in the execution of a program. We would not have any useful programs if there was never any method that did something externally, since we would never then view the results of any computation. However, a method that calculates and returns a value is in general much more useful.
{
System.out.print("The number "+num);
System.out.println(" occurs "+c+" times in the list");
}
One thing you should always avoid doing is writing methods that calculate and display a result. That is to try and make a method do two things that should be separate, and that is always a mistake. For example, I sometimes see people who are asked to write a method to do a task like "take an integer and an array of integers and return the number of times the integer occurs in the array" write something like:
void count(int m,int[] b)I call this a "useless" method. Why is it useless when it seems to do the job - calculating the number of times an integer occurs in an array? If we call it with, say:
// Deliberately silly method - never write one like this
{
int count=0;
for(int j=0; j<b.length; j++)
if(b[j]==m)
count++;
System.out.print("The number "+m);
System.out.println(" occurs "+count+" times in the list");
}
count(n,a);it will count and print the number of times the value in variable
n
occurs in the array referred to by a
.
The reason it is useless is that although it solves the problem for the purpose of the programming exercise, it could not be used any further. Once we get beyond tiny examples given as exercises for beginning programmers, when we write methods it's because we want to use the value they return to do something else with it. So if we want to count the number of times an integer occurs in an array of integers, it's because we want to save that value in a variable and use that variable elsewhere. If the value is just printed, it is cannot be used further in the program. We want to be able to write something like
num = count(n,a);and go on to use
num
. It's quite likely we will want to
use a method more than once with different arguments, for example:
num1 = count(n,a);so another advantage of methods is that they enable us to reuse portions of code.
num2 = count(m,b);
Some people, realising this, write methods like:
int count(int m,int[] b)Again, this is wrong. If you use a method as part of a larger program, the chances are you don't want some silly little message being printed whenever it is used.
// Deliberately silly method - never write one like this
{
int count=0;
for(int j=0; j<b.length; j++)
if(b[j]==m)
count++;
System.out.print("The number "+m);
System.out.println(" occurs "+count+" times in the list");
return count;
}
Another variation I have seen, is people writing methods which return the silly little message:
String count(int m,int[] b)Again, this is useless. We will always want a method which returns the number of times an integer is in an array, or whatever else it is we are calculating, as an actual value. We cannot do anything further with it if it is turned into a string.
// Deliberately silly method - never write one like this
{
int count=0;
for(int j=0; j<b.length; j++)
if(b[j]==m)
count++;
return "The number "+m+" occurs "+count+" times in the list";
}
Finally, if you are asked to write a method to do something, a
method
is required, not a whole program. For the purpose of a programming
exercise set for beginning programmers that we actually want to
execute, we will need the program with its main
method,
and simple interface to read values and pass them to the method.
However,
in a test or exam where you are asked to write a method that would
never be required, you would waste time writing it, and lose
marks for not realising it isn't needed.
So, to summarise, if you are asked in a test or exam:
Write a method which takes an integer and an array of integers and returns the number of times the integer occurs in the array.
what is required is:
public static int count(int n,int[] a)It would be wrong to write code, in answer to the request above, which either reads something or writes something. When doing exercises in the lab however, code to read/write things may be provided or may have to be written in order to be able to run the more important code that provides the algorithms and data structures.
{
int count=0;
for(int j=0; j<a.length; j++)
if(a[j]==n)
count++;
return count;
}
import java.util.*;Another possibility would be to remember that the prompts are themselves just strings, and generalise the reading methods by making the prompts parameters to them. This gives:
import java.io.*;
class CountNumber4
// A program to read a list of numbers then read one number and
// count the number of times it occurs in the list.
// Code broken up into separate static methods.
// Prompts outside reading methods
{
public static void main(String[] args) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter a list of numbers (all on one line):");
int[] a = readNumbers(in);
System.out.print("Enter a number: ");
int n = readANumber(in);
int count = count(n,a);
System.out.print("The number "+n);
System.out.println(" occurs "+count+" times in the list");
System.out.println("That's all");
}
public static int[] readNumbers(BufferedReader in) throws Exception
{
String line = in.readLine();
StringTokenizer toks = new StringTokenizer(line);
int[] a = new int[toks.countTokens()];
for(int i=0; i<a.length; i++)
a[i] = Integer.parseInt(toks.nextToken());
return a;
}
public static int readANumber(BufferedReader in) throws Exception
{
String line = in.readLine();
int n = Integer.parseInt(line);
return n;
}
public static int count(int n,int[] a)
{
int count=0;
for(int j=0; j<a.length; j++)
if(a[j]==n)
count++;
return count;
}
}
import java.util.*;
import java.io.*;
class CountNumber5
// A program to read a list of numbers then read one number and
// count the number of times it occurs in the list.
// Code broken up into separate static methods.
// Prompts as parameters to reading methods
{
public static void main(String[] args) throws Exception
{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] a = readNumbers(in,"Enter a list of numbers (all on one line):");
int n = readANumber(in,"Enter a number: ");
int count = count(n,a);
System.out.print("The number "+n);
System.out.println(" occurs "+count+" times in the list");
System.out.println("That's all");
}
public static int[] readNumbers(BufferedReader in,String prompt)
throws Exception
{
System.out.println(prompt);
String line = in.readLine();
StringTokenizer toks = new StringTokenizer(line);
int[] a = new int[toks.countTokens()];
for(int i=0; i<a.length; i++)
a[i] = Integer.parseInt(toks.nextToken());
return a;
}
public static int readANumber(BufferedReader in,String prompt)
throws Exception
{
System.out.print(prompt);
String line = in.readLine();
int n = Integer.parseInt(line);
return n;
}
public static int count(int n,int[] a)
{
int count=0;
for(int j=0; j<a.length; j++)
if(a[j]==n)
count++;
return count;
}
}
Last modified: 14 December 2004