Every programming language supports functions in two categories: (1) user-defined functions, and (2) language-supplied functions (also known as library functions). To begin with, let us start with user-defined functions.
In most object-oriented languages, either functions belong to a class or they do not belong to any particular class (free or global). In Java, every function must be a part of some class. There is no concept of free or global function.
Functions are small pieces of code doing a particular task. Functions are called methods in Java. Hence, the name of the topic should have been “methods in Java”.
So far, we have not introduced objects. Hence, you may not appreciate the significance of keyword static
at this stage. For the time being, let us assume that it is just a syntax requirement.
Let us study a simple method convert
which converts amount in rupees and paise into paise.
Problem: Write a function convert()
to convert rupees and paise into paise.
Solution: See Program 6.1.
PROGRAM 6.1 Conversion to Paise
// method2.java
class method2
{
public static void main(String args[])
{ int rupees=3;
int paise =25;
int total;
total = convert(rupees,paise);
System.out.println(“Total paise = “ + total);
}
public static int convert(int x, int y)
{ int temp;
temp = x*100 + y;
return temp;
}
}
The following output is obtained on running Program 6.1.
Output
Total paise
= 325
A method has a header line and a body.
The header line consists of
The body consists of a block. Block means zero or more statement within curly brackets. If the return type is anything other than void
, the last statement must be return
statement.
Please note that access specifier (like public or private) is optional. Also, methods may not have any parameters.
Like most programming languages, functions can call themselves. This technique is called recursion. There are both advantages and disadvantages of this technique. Let us first see a common example.
Problem: Write a function factorial using recursive technique.
Solution: See Program 6.2.
PROGRAM 6.2 Introducing Recursion
// factor5.java
// demonstrates recursion
class factor5
{ static int factorial ( int number)
{ System.out.println(“parameter value = “ + number);
if (number<=1) return 1 ;
else
return number*factorial(number -1);
};
public static void main(String args[])
{ int number = 8 ;
int result;
// it is assumed that number is >= 2 result = factorial( number );
System.out.println(“---------------------“);
System.out.println(“number=” + number);
System.out.println(“The factorial is : “ + result);
}
}
The following output is obtained on running Program 6.2.
Output
parameter value = 8
parameter value = 7
parameter value = 6
parameter value = 5
parameter value = 4
parameter value = 3
parameter value = 2
parameter value = 1
---------------------
number=8
The factorial is : 40320
Advantages of recursion: If you see the aforementioned code, there is only one critical line.
number*factorial(number -1);
It does the task of finding the factorial. It means that the code written is small and crisp (in most of the cases). Many data structures are recursive in nature. Their handling becomes easy using recursion. The tree structure is the most common example. There are two interesting programs ahead in the text which emphasize the advantage of recursion. One is listing all the files in a directory. Another builds and displays a binary search tree.
Disadvantages of recursion: If a code is not written carefully, there is a chance that program goes in a loop. Recursive methods normally require more memory and possibly more time too.
When to use recursion: As a rule of thumb, recursion should be used if we are dealing with algorithms which are recursive in nature or data structures which are recursive in definition (e.g. tree).
When not to use recursion: Recursion should not be used when we can code without it without any difficulty. Hence, factorial is not a good case for recursion.
Right from our school days, we know that most of the functions have parameters. Consider method sin(x). Here x is the parameter. The method calculates the value of sine of x. In this sense, parameter x is an input to the method.
The basic method of passing parameters in Java is pass-by-value. It means that if the method modifies the parameter, its effect will not remain after the method is over. It may be noted that in other languages like Pascal and C/C++, parameters can be passed in two different ways (pass-by-value and pass-by-reference).
Passing of parameters can be divided into two sections: (1) passing parameters of simple or primitive type (like int
and char
), and (2) passing parameters aggregate of type (like objects or arrays).
Ordinary parameters are passed-by-value. This implies that when a method modifies it; the modified value will exist till the method is running. As soon as the method ends (returns), value of the parameter will be as earlier. In other words, copy of the parameter is passed. Hence, the original parameter value remains intact.
Let us try a simple program.
Problem: Write a program to show that the method clear()
fails to clear an integer parameter.
Solution: See Program 6.3.
PROGRAM 6.3 Passing Parameters
// para1.java
class para1
{ public static void main(String args[])
{ int marks = 95 ;
System.out.println(“--->para1.java<---“);
System.out.println(“ before clear marks = “ + marks);
clear(marks);
System.out.println(“ after clear marks = “ + marks);
}
public static void clear(int n)
{ n = 0;
}
}
The following output is obtained on running Program 6.3.
Output
--->para1.java<---
before clear marks = 95
after clear marks = 95
Figure 6.1 Pass-by-Value
The principle of Program 6.3 can be shown in Figure 6.1.
Can you imagine what will happen if someone writes a method swap
for swapping two integers? Program 6.3 tells us that such a method would simply fail. If we want to swap two integers, say m and n (or any simple variables for that matter), we should write the standard three line code in place of function swap
. The code is as follows:
temp = m;
m=n ;
n= temp;
So far we have seen simple data types as parameters. In Java, we can also pass objects as parameters. As mentioned earlier, there is only one way to pass parameters, that is pass-by-value. This is true. But in Java, objects are created with the help of object reference (something like a pointer in C/C++). Hence, when we pass objects as parameter, they effectively get passed by reference. Hence, changes made by a method are seen even after the method is over.
Java creates arrays and strings with the help operator new
. Java treats them as objects. Therefore, passing arrays or strings also behaves in the same manner.
Let us write a small program and test how an array behaves when passed as a parameter.
Problem: Write a program to demonstrate the fact that when an array is passed as a parameter, it is passed by reference.
Solution: See Program 6.4.
PROGRAM 6.4 Array as Parameter
// ref1.java
class ref1
{ public static void main(String args[])
{ int A[]= { 20, 30, 40, 50, 60 };
int i, n = 5 ;
System.out.println(“before clear A[3] = “ +A[3]);
clear(A,n);
System.out.println(“after clear A[3] = “ +A[3]);
}
public static void clear(int X[],int n)
{ int i;
for(i=0;i<n;i++)
X[i] =0;
}
}
The following output is obtained on running Program 6.4.
Output
before clear A[3] = 50
after clear A[3] = 0
The principle of passing parameters by reference is shown in Figure 6.2.
swap
Swapping is a very common process in programming. It is needed in many applications. Sorting is a common example. Swapping means exchanging. Let us see what happens if we try to write method swap
for swapping objects.
Earlier we had mentioned that ordinary variables cannot be swapped. But the previous example has shown that the contents of an object can change. It means that swapping of objects is possible. Let us try it in a program.
Figure 6.2 Pass-by-Reference
Problem: Write a program to demonstrate the method swap
to exchange two objects.
Solution: See Program 6.5.
PROGRAM 6.5 Swapping Objects I
// swap1.java
class marks
{ int a;
}
class swap1
{ public static void main(String args[])
{ marks ramesh,suresh;
ramesh=new marks();
suresh=new marks();
ramesh.a=90;
suresh.a=80;
swap(ramesh,suresh);
System.out.println(“--->swap1.java starts<---“);
System.out.println(“Ramesh “ + ramesh.a );
System.out.println(“Suresh “ + suresh.a );
}
static void swap(marks X,marks Y)
{ marks temp=new marks();
temp=X;
X=Y;
Y=temp;
}
}
The following output is obtained on running Program 6.5.
Output
--->swap1.java starts<---
Ramesh 90
Suresh 80
We observe that the desired result “swapping of objects” is not obtained on running Program 6.5. To obtain the desired result, let us study Program 6.6.
Problem: Write a program to demonstrate method SWAP
to swap
the two objects.
Solution: See Program 6.6.
PROGRAM 6.6 Swapping Objects II
// swap2.java
class marks
{ int a;
}
class swap2
{ public static void main(String args[])
{ marks ramesh,suresh;
ramesh=new marks();
suresh=new marks();
ramesh.a=90;
suresh.a=80;
SWAP(ramesh,suresh);
System.out.println(“--->swap2.java starts<---“);
System.out.println(“Ramesh “ + ramesh.a );
System.out.println(“Suresh “ + suresh.a );
}
static void SWAP(marks X,marks Y)
{ marks temp=new marks();
temp.a=X.a;
X.a=Y.a;
Y.a=temp.a;
}
}
The following output is obtained on running Program 6.6.
Output
--->swap2.java starts<---
Ramesh 80
Suresh 90
Now, the desired result is obtained. Please note that when we swap objects in a method we should swap all the fields of the objects individually. (Concept of fields will be clear when we discuss objects in Chapter 7.)
Let us summarize the process of swapping.
temp = a;
a = b;
b = temp;
Simple code, no parameters no methods! If you want to swap p and q at some other place, write a similar (not same) code at that place.
swap
. That method should swap all fields individually as shown in Program 6.6.Java has defined many packages and classes for the use of the programmer. They contain highly useful methods. Since all of us are familiar with number crunching and mathematics, let us have a look at methods found in class Math
. Table 6.1 summarizes the important methods from class Math
.
Table 6.1 Methods Summary: Class Math
Please note that Table 6.1 contains many transcendental functions. The functions which are not algebraic are called transcendental functions. These functions include exponential and trigonometric functions.
We will see a few methods in action in Section 6.6. Java provides many useful classes. These classes provide programmers with useful methods. These methods will be discussed as and when needed.
A story from a village goes as follows. A poor old man celebrated his hundredth birthday. All the villagers were thrilled with the idea that someone from their village could be so lucky. They contributed generously and presented a purse of Rs. 1000 to him. The old man said, “If I had got this gift at my birth, I would have been ‘Karodpati’ by now”.
Let us test whether what the old man thought is accurate or not with the help of a program.
Problem: Write a program to demonstrate the power of method pow()
from class Math
.
Solution: Assume that the villager in the aforementioned story deposited the money in a bank at 10% compound interest.
Normally, we use R for rate specified as percent. Then r is used as rate per unit and is calculated as R/100.
If one invests Re. 1 at rate r per unit, after N years he gets back (1 + r) raised to N.
Hence, method pow
is handy in calculations.
See Program 6.7.
PROGRAM 6.7 Use of Method pow()
// pow1.java
class pow1
{
public static void main(String args[])
{ double deposit= 1000.00 ;
double R = 10.0 ;
double r = R /100.0 ;
double amount=0;
System.out.println(“<---pow1.java--->”);
amount = deposit * Math.pow( (1.0+r) , 100);
System.out.println(“The amount is : “ + (long)amount);
}
}
The following output is obtained on running Program 6.7.
Output
<---pow1.java--->
The amount is : 13780612
The method atan()
helps us getting arctan in the range –pi/2 to +pi/2. If we consider a problem of rectangular to polar coordinates, we want angle in all possible (four) coordinates. Hence, Java supplies an additional method atan2()
. Let us check it in action.
Problem: Write a program to find an angle theta for a point with given x and y coordinates.
Solution: For simplicity, let us take a condition x = y. If the point is in the first quadrant, the angle should be pi/4. If the point is in the third quadrant, the angle should be 3*pi/4. Figure 6.3 illustrates the use of method atan()
to find angle theta.
See Program 6.8.
PROGRAM 6.8 Method atan2()
// pt1.java
class pt1
{
public static void main(String args[])
{ double x1 = 1.0, y1=1.0 ;
double x3 = -1.0,y3=-1.0 ;
double theta1,theta3 ;
double pi_by_4= Math.PI / 4.0;
System.out.println(“<---pt1.java--->”);
System.out.println(“pi_by_4 is : “ + pi_by_4);
theta1 = Math.atan2( x1 , y1);
Figure 6.3 Method atan2()
System.out.println(“Theta1 is : “ + theta1);
theta3 = Math.atan2( x3 , y3);
System.out.println(“Theta3 is : “ + theta3);
}
}
If you run the program, you will get following output.
Output
<---pt1.java--->
pi_by_4 is : 0.7853981633974483
Theta1 is : 0.7853981633974483
Theta3 is : -2.356194490192345
Actually, method atan2
is developed (written) very carefully. It takes care of many special cases regarding the parameter values. Readers are requested to see the relevant documentation.
array as parameter, atan()
, atan2()
, class Math
, objects as parameters, pass-by-reference, pass-by-value, pow()
, recursion, swap
In C++, it is possible to pass objects both by value or by reference. In Java basic data types are passed by value and aggregate data types are effectively passed by reference. In this sense, C++ is richer than Java.
In C++, a local variable of a function can be declared as static. It retains the value after the execution of that function is over. This is not allowed in Java.
swap
is not available for simple (in-built) data types?18.216.44.143