Lesson 10: Methods
Understanding method definition, invocation, overloading, and scope.
Contents
Introduction
Important: Methods are used to describe reusable code and to simplify programming.
Suppose you need to find the sum of integers from 1 to 10, from 20 to 37, and from 35 to 49, respectively. For this case, you could write the following code snippets:
int sum = 0; for (int i = 1; i <= 10; i++) sum += i; System.out.println("Sum from 1 to 10 is " + sum);
sum = 0; for (int i = 20; i <= 37; i++) sum += i; System.out.println("Sum from 20 to 37 is " + sum);
sum = 0; for (int i = 35; i <= 49; i++) sum += i; System.out.println("Sum from 35 to 49 is " + sum);
You may notice that the computations for the sums from 1 to 10, from 20 to 37, and from 35 to 49 are very similar except that the starting and ending integers are different. Wouldn't it be nice if we could write a common code once and reuse it? We can do this by defining a method and invoking it.
The previous code snippets can be simplified as follows:
1 public static int sum(int i1, int i2) { 2 int result = 0; 3 for (int i = i1; i <= i2; i++) 4 result += i; 5 6 return result; 7 } 8 9 public static void main(String[] args) { 10 System.out.println("Sum from 1 to 10 is " + sum(1, 10)); 11 System.out.println("Sum from 20 to 37 is " + sum(20, 37)); 12 System.out.println("Sum from 35 to 49 is " + sum(35, 49)); 13 }
Lines 1–7 define a method named sum with two parameters i1 and i2. The statements in the main() method invoke the method: sum(1, 10) to compute the sum from 1 to 10, sum(20, 37) to compute the sum from 20 to 37, and sum(35, 49) to compute the sum from 35 to 49.
Important: A method is a collection of statements grouped together to perform an operation.
Method Definition
Important: A method definition consists of the method name, parameters, return type, and method body.
Syntax of method definition:
/* What the method does */ modifiers returnType methodName(list of parameters) { // method body }
Let's examine a method defined to find the maximum of two integers. This method, named max, has two parameters of type int, num1 and num2, and returns the larger value. The components of this method are shown below:
public static int max(int num1, int num2) { int result; if (num1 > num2) { result = num1; } else { result = num2; } return result; }
The method header defines the modifiers, return type, method name, and parameters. The static modifier is used for all methods in this lesson. All methods or functions must be static, which means you can call them without creating an object of the class.
A method may return a value. The returnType is the data type of the value the method returns. Some methods perform required operations without returning a value. In this case, the returnType is the keyword void. For example, the main() method, as well as the System.exit() and System.out.println() methods, have a void return type. If a method returns a value, it is called a value-returning method; otherwise, it is called a void method.
The variables defined in the method header (int num1, int num2) are called formal parameters, or simply parameters. When a method is invoked, a value is passed to the parameter. This value is referred to as an actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a method. The method name and the parameter list together constitute the method signature. Parameters are optional; that is, a method may contain no parameters. For example, the Math.random() method has no parameters.
The method body contains a collection of statements that implement the method. In the max() method body, an if statement is used to determine which number is larger, and that number is returned. A value-returning method requires a return statement to return a result. The method terminates when a return statement is executed.
Important: Each parameter in the method header must have a separate declaration. For example, the header max(int num1, int num2) is valid, but max(int num1, num2) is invalid.
Method Invocation
When a method is invoked, the code inside the method is executed.
A method definition specifies what the method does. To execute a method, you need to invoke (call) it. There are two ways to invoke a method, depending on whether it returns a value or not.
If a method returns a value, the method invocation is usually treated as a value. For example, the statement:
int larger = max(3, 4);
invokes max(3, 4) and assigns the result of the method to the variable larger. Another example of invocation treated as a value is the statement:
System.out.println(max(3, 4));
which prints the value returned by the max(3, 4) method.
If a method returns nothing (i.e., its return type is void), a call to the method must be a statement. For example, the println() method returns nothing. The following call is a statement:
System.out.println("Welcome!");
Important: Return type is used to indicate what type the method will return. Use void if the method will not return a value, or any supported data type.
When a method is invoked, the program control transfers to the called method. A called method returns control to the caller when its return statement is executed or when its closing brace is reached.
The following program TestMax is used to test the max() method.
public class TestMax { /** * Main method */ public static void main(String[] args) { int i, j, k; i = 5; j = 2; k = max(i, j); // invoke max method System.out.println("The maximum of " + i + " and " + j + " is " + k); } /** * Returns the maximum of two numbers */ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2; return result; // return result } }
The TestMax program contains the main() method and the max() method. The main() method is just like any other method except that it is invoked by the JVM to start the program.
The header of the main() method is always the same. Like the one in the TestMax program, it includes the modifiers public and static, return type void, method name main, and a parameter of the type String[]. String[] indicates that the parameter is an array of strings. The concept of arrays will be introduced in the following lessons of this course.
Statements in the main() method may invoke other methods that are defined in the class containing the main() method or in other classes. In the TestMax program, the main() method invokes max(i, j), which is defined in the same class as the main() method.
When the max() method is invoked (line 9), variable i's value 5 is passed to num1, and variable j's value 2 is passed to num2 in the max() method. The flow of control transfers to the max() method, and the max() method is executed. When the return statement in the max() method is executed, the max() method returns control to the caller (the main() method).
Important: A return statement is required for a value-returning method. The method on the left is logically correct, but it has a compilation error because the Java compiler thinks that this method might not return a value.
public static int sign(int n) { if (n > 0) return 1; else if (n == 0) return 0; else if (n < 0) return -1; }
public static int sign(int n) { if (n > 0) return 1; else if (n == 0) return 0; else return -1; }
To fix this problem, delete if (n < 0) on the left so that the compiler will see a return statement to be reached regardless of how the if statement is evaluated.
Important: Methods enable code sharing and reuse. The max method can be invoked from any class besides TestMax. If you create a new class, you can invoke the max method using ClassName.methodName() (i.e., TestMax.max()).
Call Stack
Each time a method is invoked, the system creates an activation record (also called an activation frame) that stores parameters and variables for the method and places it in an area of memory known as the call stack. A call stack is also known as an execution stack, machine stack, or simply the stack. When a method calls another method, the caller's activation record is kept unchanged, and a new activation record is created for the new method called. When the method finishes its work and returns to its caller, its activation record is removed from the call stack.
The call stack stores activation records in a last-in, first-out (LIFO) fashion. The activation record for the method that is invoked last is removed first from the stack. For example, suppose method m1 calls method m2, and method m2 calls method m3. The system places m1's activation record first, then m2's, and finally m3's in the stack. After method m3 finishes its execution, its activation record is removed from the stack. After method m2 finishes its execution, its activation record is removed from the stack. After method m1 finishes its execution, its activation record is removed from the stack.
Understanding the call stack helps you understand how methods are invoked. The variables defined in the main method of the TestMax program are i, j, and k. The variables defined in the max method are num1, num2, and result. The variables num1 and num2 are defined in the method signature and are parameters of the max method. Their values are passed through method invocation. The following figure illustrates the activation records of methods in the call stack.
To call a method, you specify the method name and provide any arguments that correspond to the method parameters in parentheses:
int z = max(2, 5); System.out.println(z);
Complete program:
public class L10Max { public static int max(int num1, int num2) { int result; if (num1 > num2) { result = num1; } else { result = num2; } return result; } public static void main(String[] args) { int z = max(2, 5); System.out.println(z); } }
Void Methods
A void method does not return a value.
In the previous section, we gave an example of a value-returning method. In this section, we will show how to define and invoke a void method. The following program TestVoidMethod defines a method named printGrade and invokes it to print the grade for a given score.
public class TestVoidMethod { public static void main(String[] args) { System.out.print("The grade is "); printGrade(78.5); System.out.print("The grade is "); printGrade(59.5); } public static void printGrade(double score) { if (score >= 90.0) { System.out.println('A'); } else if (score >= 80.0) { System.out.println('B'); } else if (score >= 70.0) { System.out.println('C'); } else if (score >= 60.0) { System.out.println('D'); } else { System.out.println('F'); } } }
The printGrade method is a void method because it does not return any value. A call to a void method must be a statement. So, it is invoked as a statement in line 4 in the main method. Like any Java statement, it is terminated with a semicolon.
To see the difference between a void method and a value-returning method, let us redesign the printGrade method to return a value. The new method, which we name getGrade, returns the grade as shown in the program TestReturnGradeMethod:
public class TestReturnGradeMethod { public static void main(String[] args) { System.out.print("The grade is " + getGrade(78.5)); System.out.print("\nThe grade is " + getGrade(59.5)); } public static char getGrade(double score) { if (score >= 90.0) return 'A'; else if (score >= 80.0) return 'B'; else if (score >= 70.0) return 'C'; else if (score >= 60.0) return 'D'; else return 'F'; } }
The getGrade method defined in lines 7–18 returns a character grade based on the numeric score. The main method invokes this method in lines 3 and 4.
The getGrade method can be invoked anywhere that a character value appears. The printGrade method does not return a value, so it must be invoked as a statement.
Important: A void method does not require a return statement, but it may be used to terminate the method and return to the method's caller. The syntax is simply:
return;
This is not often done in void methods, but it is sometimes useful for circumventing the normal flow of control. For example, the following code fragment has a return statement to terminate the method when the score is invalid:
public static void printGrade(double score) { if (score < 0 || score > 100) { System.out.println("Invalid score"); return; } if (score >= 90.0) { System.out.println('A'); } else if (score >= 80.0) { System.out.println('B'); } else if (score >= 70.0) { System.out.println('C'); } else if (score >= 60.0) { System.out.println('D'); } else { System.out.println('F'); } }
Passing Arguments
There are two approaches that you can use:
- Pass by value
- Pass by reference (note: Java is strictly pass-by-value, but reference types pass a copy of the reference)
Take a look at the following two examples:
// 1. public static void main(String[] args) { int a = 1; plus2(a); System.out.println(a); // result will be 1 } static void plus2(int a) { a += 2; }
// 2. public static void main(String[] args) { int a = 1; a = plus2(a); // assign the result System.out.println(a); // prints 3 } static int plus2(int a) { return a + 2; }
When calling:
public class Main { public static void main(String[] args) { int a = plus2(); // get value from method System.out.println(a); // prints 3 } static int plus2() { int a = 1; a += 2; return a; } }
Passing Arguments to Parameters
The power of a method is its ability to work with parameters. You can use println to print any string and max to find the maximum of any two int values. When calling a method, you need to provide arguments, which must be given in the same order as their respective parameters in the method signature. This is known as parameter order association. For example, the following method prints a message n times:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i++) System.out.println(message); }
You can use nPrintln("Hello", 3) to print Hello three times. The statement nPrintln("Hello", 3) passes the actual string parameter Hello to the formal parameter message, passes 3 to n, and prints Hello three times. However, the statement nPrintln(3, "Hello") would be incorrect. The data type of 3 does not match the data type for the first parameter, message, and the second argument, "Hello", does not match the second parameter, n.
Caution: The arguments must match the parameters in order, number, and compatible type, as defined in the method signature. Compatible type means that you can pass an argument to a parameter without explicit casting, such as passing an argument of type int to a parameter of type double.
When you invoke a method with an argument, the value of the argument is passed to the parameter. This is referred to as pass-by-value. If the argument is a variable rather than a literal value, the value of the variable is passed to the parameter. Regardless of changes to the parameter's value inside the method, the variable's value is not affected. As shown in the program Increment, the value of x (1) is passed to the parameter n to invoke the increment method (line 5). Inside the method, n is incremented (line 10), but the value of x remains unchanged regardless of what happens in the method.
public class Increment { public static void main(String[] args) { int x = 1; System.out.println("Before the call, x is " + x); increment(x); System.out.println("After the call, x is " + x); } public static void increment(int n) { n++; System.out.println("Inside the method, n is " + n); } }
The program TestPassByValue demonstrates the effects of passing arguments by value. The program creates a method for swapping two variables. The swap method is invoked with two arguments. Interestingly, the values of the arguments are not changed after the method is invoked.
public class TestPassByValue { /** Main method */ public static void main(String[] args) { int num1 = 1; int num2 = 2; System.out.println("Before invoking the swap method, num1 is " + num1 + " and num2 is " + num2); // Invoke the swap method to attempt to swap two variables swap(num1, num2); System.out.println("After invoking the swap method, num1 is " + num1 + " and num2 is " + num2); } /** Swap two variables */ public static void swap(int n1, int n2) { System.out.println("\tInside the swap method"); System.out.println("\t\tBefore swapping, n1 is " + n1 + " and n2 is " + n2); // Swap n1 with n2 int temp = n1; n1 = n2; n2 = temp; System.out.println("\t\tAfter swapping, n1 is " + n1 + " and n2 is " + n2); } }
Before the swap method is invoked (line 9), num1 is 1 and num2 is 2. After the swap method is invoked (line 15), num1 is still 1 and num2 is still 2. Their values have not been swapped. As shown in the following figure, the values of the arguments num1 and num2 are passed to n1 and n2, but n1 and n2 have their own memory locations independent of num1 and num2. Therefore, changes in n1 and n2 do not affect the contents of num1 and num2.
Diagram: Memory locations for num1, num2, n1, and n2 showing pass-by-value.
Another subtle point: changing the parameter name n1 to num1 inside the swap method. What effect does this have? No change occurs, because it makes no difference whether the parameter and the argument have the same name. The parameter is a variable inside the method with its own memory space. The variable is allocated memory when the method is invoked, and it is deallocated when the method is returned.
Method Overloading
Important: Method overloading allows you to define multiple methods with the same name if their parameter lists are different.
The max method used earlier works only with the int data type. But what if you need to find which of two floating-point numbers has the larger value? The solution is to create another method with the same name but different parameters, as shown in the following code:
public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2; }
When you call max with int parameters, the max method that expects int parameters is invoked; when you call max with double parameters, the max method that expects double parameters is invoked. This is referred to as method overloading; that is, two methods have the same name but different parameter lists within one class. The Java compiler determines which method is used based on the method signature.
The program TestMethodOverloading defines three methods. The first finds the maximum integer, the second finds the maximum double, and the third finds the maximum among three double values. All three methods are named max.
public class TestMethodOverloading { /** Main method */ public static void main(String[] args) { // Invoke the max method with int parameters System.out.println("The maximum of 3 and 4 is " + max(3, 4)); // Invoke the max method with double parameters System.out.println("The maximum of 3.0 and 5.4 is " + max(3.0, 5.4)); // Invoke the max method with three double parameters System.out.println("The maximum of 3.0, 5.4, and 10.14 is " + max(3.0, 5.4, 10.14)); } /** Return the max of two int values */ public static int max(int num1, int num2) { if (num1 > num2) return num1; else return num2; } /** Return the max of two double values */ public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2; } /** Return the max of three double values */ public static double max(double num1, double num2, double num3) { return max(max(num1, num2), num3); } }
When calling max(3, 4) (line 8), the max method for finding the maximum of two integers is invoked. When calling max(3.0, 5.4) (line 12), the max method for finding the maximum of two doubles is invoked. When calling max(3.0, 5.4, 10.14) (line 16), the max method for finding the maximum of three doubles is invoked.
Can you invoke the max method with an int value and a double value, such as max(2, 2.5)? If so, which of the max methods is invoked? The answer to the first question is yes. The answer to the second is that the max method for finding the maximum of two double values is invoked. The argument value 2 is automatically converted into a double value and passed to this method.
You may be wondering why the method max(double, double) is not invoked for max(3, 4). Both max(double, double) and max(int, int) are possible matches for max(3, 4). The Java compiler finds the method that best matches a method invocation. Since the method max(int, int) is a better match for max(3, 4) than max(double, double), max(int, int) is used to invoke max(3, 4).
Overloading methods can make programs clearer and more readable. Methods that perform closely related tasks should be given the same name.
Important: Overloaded methods must differ in at least the parameter list. You cannot overload methods based on different return types. You cannot overload methods based on different modifiers.
Important: Sometimes there are two or more possible matches for an invocation of a method, but the compiler cannot determine the most specific match. This is referred to as ambiguous invocation. Ambiguous invocation causes a compilation error. Consider the program AmbiguousOverloading:
public class AmbiguousOverloading { public static void main(String[] args) { System.out.println(max(1, 2)); } public static double max(int num1, double num2) { if (num1 > num2) return num1; else return num2; } public static double max(double num1, int num2) { if (num1 > num2) return num1; else return num2; } }
Both the max(int, double) and max(double, int) methods are possible candidates for the call max(1, 2). Since neither is more specific than the other, the invocation is ambiguous, resulting in a compilation error.
Variable Scope
Important: The scope of a variable is the part of the program where the variable can be referenced.
A variable declared inside a method is referred to as a local variable. The scope of a local variable starts from its declaration and continues to the end of the block that contains the variable. A local variable must be declared and assigned a value before it can be used.
A parameter is actually a local variable. The scope of a method parameter covers the entire method. A variable declared in the header of a for loop has its scope in the entire loop. However, a variable declared inside a for loop body has its scope limited in the loop body from its declaration to the end of the block that contains the variable.
You can declare a local variable with the same name multiple times in non-nested blocks in a method, but you cannot declare a local variable twice in nested blocks. This is illustrated in the following figure.
Important: A common mistake is to declare a variable inside a for loop and then attempt to use it outside the loop. As shown in the following code, variable i is declared inside the for loop, and an attempt to access it outside the loop causes a syntax error.
for (int i = 0; i < 10; i++) { // ... } System.out.println(i); // Causes a syntax error
The last statement would cause a syntax error because variable i is not defined outside the for loop.
Laboratory Work
Lab 1: Argument and Overloading
To do: Create a Sum() method that takes two integer arguments and sums them. The method returns no value (which is why you have to use void).
Note: We need to use the static keyword in the method signature because the main function is static and we cannot call a non-static method from a static method.
File name: L10Lab1.java
Expected output:
20 40
The sum of 20 and 40 is: 60
Algorithm:
- Create a new Java file named
L10Lab1.java. - Import the
Scannerclass for input. - In the
mainfunction, request the user to input two numbers:import java.util.Scanner; ... System.out.println("Please enter two numbers"); int a = 0, b = 0; Scanner scanner = new Scanner(System.in); a = scanner.nextInt(); b = scanner.nextInt(); ...
- Place your cursor after the closing curly brace of the
static void main(String[] args)function and press Enter. We are doing this because you don’t want to place methods/functions inside another function. - Declare a new method called
Sum()that will be used to add values passed into it:The method doesn’t return any value to the main program, which is why we have to use the... static void sum(int first, int second) { int sum = first + second; System.out.printf("The sum of %d and %d is: %d%n", first, second, sum); } ...
voidkeyword. The method calculates the sum of two values passed in. - Now we can call this method from within the
mainfunction. Enter the following code within the curly braces ofmain():public static void main(String[] args) { ... sum(a, b); // method call }
- Run the program (e.g., press F5 in your IDE).
- The function
sum()we’ve created doesn’t return a value. We will now modify that method so that it returns the result to the calling method (to themainmethod from where it was called). - Comment the code of the
sum()function using the shortcut key [CTRL]+K+C (or appropriate comment style in your IDE)://static void sum(int first, int second) //{ // int sum = first + second; // System.out.printf("The sum of %d and %d is: %d%n", first, second, sum); //} - Place your cursor after these comments and enter the following code:
The method returns an integer value, which is why we use
... static int sum(int first, int second) { int sum = first + second; return sum; } ...
intin the signature (static int sum(...)). Notice that the parameters’ names we have specified here in the method may not match the names of the arguments we have passed in. They become local variables within the scope of this method. - Then we need to modify the code in
main(). We have to change the way to call the method. Declare an integer variable to receive the return value. Print out the result to the console window.... public static void main(String[] args) { ... int result = sum(a, b); System.out.println("The sum of " + a + " and " + b + " is " + result); } ...
- Run the application again and check the output. Both outputs should be the same.
Overloading the method (function):
Overloading Methods means having a method with the same name but different signatures.
- Let’s now overload our
sum()method. To do it we will create two additional methods with the same names. - Place your cursor after the
sum()method code. First, create a method that accepts three integers by entering the following code:This method uses the same name as thestatic int sum(int first, int second, int third) { int sum = first + second + third; return sum; }
sum()method that takes two integers, but the parameters here indicate the method is expecting three integers as arguments. The compiler knows which method to call based on the number of arguments passed in. - Next, enter the following code that will create a
sum()method that accepts two doubles as arguments:This method uses the same name as the... static double sum(double first, double second) { double result = first + second; return result; } ...
sum()method that takes two integers, but the parameters here indicate the method is expecting two doubles as arguments. The compiler knows which method to call based on the arguments data types. - Finally, modify the code in
main()that calls the methods:... int result = sum(a, b); System.out.println("Calling Sum() with two arguments, result is: " + result); int result3 = sum(10, 50, 80); System.out.println("Calling Sum() with three arguments, result is: " + result3); double dblResult = sum(20.5, 30.6); System.out.println("Calling Sum() that takes doubles result in: " + dblResult); ...
- Run the application again and check the output. You should see the correct summed values displayed for each call of the three different methods. Even though they are all named
sum, the compiler works out the correct method to call based on the method signature. That is how method overloading works. - Upload the file into the Moodle system.
Lab 2: Building an Exponent Function
To do: Create a getPow() method that takes two integer arguments: a base number and a power number. The method returns the result of taking a base number to a power number (an exponent).
Note 1: We need to use static in the method signature because the main function is static and we cannot call a non-static method from a static method.
Note 2: The function returns an integer value, which is why you have to use int in the signature of the function: static int getPow(int baseNum, int powNum) {…}
Expected output:
2 4
Base number 2 raised to the power number 4 = 16
File name: L10Lab2.java
Algorithm:
- Create a new Java file named
L10Lab2.java. - Import the
Scannerclass for input. - After a closing curly brace of the
mainfunction, type the signature of thegetPowfunction:The function expects two integer numbers –static int getPow(int baseNum, int powNum) { ... }
baseNumargument andpowNumargument. Inside the function, we’re going to take thebaseNumto the power ofpowNum. - Declare a variable
resultto return its value from the function as a result.int result = 1; ... return result;
- Inside the function, create a
forloop to keep multiplying theresultvariable bybaseNumpowNumtimes:The first time we go through the loop we always havefor (int i = 0; i < powNum; i++) { result = result * baseNum; }
1 * baseNumand store the result in theresultvariable. The second time we havebaseNum * baseNum. The third –baseNum * baseNum * baseNum, etc. We repeat it each iteration. - Within the
mainfunction, call the method:getPow(2, 4);
- Run the application and check the output.
- Instead of the particular numbers (2 and 4), prompt the user to input two numbers and change the code for calling the function:
System.out.println("Please enter two numbers – a base number and a power number: "); int a = scanner.nextInt(); int b = scanner.nextInt(); System.out.println(getPow(a, b)); scanner.close();
- Run the application again and check the output.
- Save and upload the file into the Moodle system.
Lab 3: Public and Private Modifiers. Calculating Product of Numbers Divisible by 3
To do: Create a project where a method calculates the product of all integers divisible by 3 in the range from A to B (inclusive). Call the method from the main function.
Expected output:
3
9
The result is 162
Project name: Lesson_10Lab3
File name: L10Lab3.java
Step-by-Step Algorithm:
- Step 1. Creating the project and class file
- Create a new project in your IDE (e.g., IntelliJ IDEA or Eclipse) named
Lesson_10Lab3. - Add a new Java class file named
L10Lab3.java.
- Create a new project in your IDE (e.g., IntelliJ IDEA or Eclipse) named
- Step 2. Creating a separate class for calculations (Class1.java)
Create a separate class
Class1.javawhere the method for calculating the product will be implemented.Code for
Class1.java:public class Class1 { // Public static method to calculate the product of numbers divisible by 3 public static int calculateProduct(int a, int b) { int product = 1; // Initialize variable to store product // Loop to iterate from a to b for (int i = a; i <= b; i++) { if (i % 3 == 0) { // Check if number is divisible by 3 product *= i; // Multiply product by current number } } return product; // Return the result } }
Explanation:
public– the method is accessible from other classes.static– the method can be called without creating an object of the class.int– the method returns an integer (the product).- The
forloop iterates fromatob. - The condition
i % 3 == 0checks divisibility by 3. product *= imultiplies the currentproductbyi.
- Step 3. Main program (L10Lab3.java)
In the file
L10Lab3.java, implement data input and call the method fromClass1.Code for
L10Lab3.java:import java.util.Scanner; public class L10Lab3 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Ask the user to enter two numbers System.out.println("Enter two integers:"); int a = scanner.nextInt(); // First number (lower bound) int b = scanner.nextInt(); // Second number (upper bound) // Call the method from Class1 and save the result int result = Class1.calculateProduct(a, b); // Output the result System.out.println("The result is " + result); } }
Explanation:
- Import
Scannerfor console input. - Create a
Scannerobject to read input. - Prompt for and read two integers (
aandb). - Call the
calculateProductmethod fromClass1, passingaandb. - Print the result.
- Import
- Step 4. Running and debugging
- Save both files (
Class1.javaandL10Lab3.java). - Run the program (Run or F5 in your IDE).
- Enter two numbers, for example:
- First number: 3
- Second number: 9
- The program will output:
The result is 162(since 3 × 6 × 9 = 162).
- Save both files (
Summary:
Class1.javacontains thecalculateProductmethod withpublic staticmodifiers, accessible from other classes.L10Lab3.javais the main program that prompts the user for a range and calls the method fromClass1.- The program correctly calculates the product of numbers divisible by 3 in the given range.
Lab 4: Calculating Product Cost
To do: Write a program that calculates the total cost of a product. Data used for calculation: unit cost in rubles, quantity of units, inclusion/exclusion of VAT (20%) in the product cost. If the quantity of units is greater than or equal to 10, a 5% discount applies.
Hint: Use overloaded methods to obtain the total cost.
Expected output:
For testing, let's input unit cost = 5, quantity = 10. When prompted to include VAT, enter an answer not in the suggested options. The same prompt reappears because we entered an invalid value. Enter "do not include VAT". The calculated cost is 47.5.
Check another execution path: input unit cost = 10, quantity = 5. Include VAT. The calculated cost is 60.
Project name: Lesson_10Lab4
File name: L10Lab4.java
Step-by-Step Algorithm:
- Create a new Java file named
L10Lab4.java. - Import the required classes:
import java.util.Scanner; - Define the class
L10Lab4with amainmethod. - Inside
main, create aScannerobject for input.import java.util.Scanner; public class L10Lab4 { public static void main(String[] args) { // ... } }
- First, inside the class, declare constants:
- 5% discount;
- VAT rate 20%.
static final int DISCOUNT_FIVE = 5; // discount in % static final double VALUE_ADDED_TAX = 20; // VAT rate in %
- Inside the
main()method, declare variables needed for calculations; three of them are for user input data, the fourth is for the calculation result.double unitCost; // unit cost of the product int amount; // quantity of the product String includeVatResponse; // include VAT in cost double fullCost; // total cost
- First, get the unit cost in rubles from the console.
Scanner input = new Scanner(System.in); // Get unit cost System.out.print("Enter unit cost of the product: "); unitCost = input.nextDouble();
- Next, get the quantity from the console.
// Get quantity System.out.print("Enter quantity of the product: "); amount = input.nextInt();
- Get the answer to whether to include VAT.
Use a
do-whileloop to validate input.// Get answer on VAT inclusion until a correct value is entered do { System.out.print("Include VAT in cost (y/n): "); includeVatResponse = input.next(); } while (!"y".equalsIgnoreCase(includeVatResponse) && !"n".equalsIgnoreCase(includeVatResponse));
- Then add a new algorithm step as a comment.
// Get total cost based on the obtained data - Organize the new algorithm step using a two-way
if-elseselection structure, each branch of which contains another nestedif-elsestructure. Thus we get four alternative execution paths.if ("y".equalsIgnoreCase(includeVatResponse)) { // include VAT in cost if (amount >= 10) { // apply discount } else { // no discount } } else { // do not include VAT in cost if (amount >= 10) { // apply discount } else { // no discount } }
- Implement a method to get the total cost without VAT and without discount.
/** * Get total cost without VAT and without discount */ public static double getFullCost(double unitCost, int amount) { return unitCost * amount; }
- For getting cost without VAT but with discount, use method overloading and create a method with the same name, adding discount as a parameter.
/** * Get total cost without VAT but with discount */ public static double getFullCost(double unitCost, int amount, int discount) { double priceWithDiscount = unitCost * (1 - discount / 100.0) * amount; // price with discount return Math.round(priceWithDiscount * 100) / 100.0; // round to kopecks }
- Again, use method overloading for calculating cost including VAT but without discount.
/** * Get total cost including VAT but without discount */ public static double getFullCost(double unitCost, int amount, double valueAddedTax) { double priceWithoutVAT = unitCost * amount; // price without VAT double priceWithVAT = priceWithoutVAT * (1 + valueAddedTax / 100); // price with VAT return Math.round(priceWithVAT * 100) / 100.0; // round to kopecks }
- And again overload the method for calculating cost including VAT and with discount.
/** * Get total cost including VAT and with discount */ public static double getFullCost(double unitCost, int amount, int discount, double valueAddedTax) { double priceWithoutVAT = unitCost * (1 - discount / 100.0) * amount; // price with discount double priceWithVAT = priceWithoutVAT * (1 + valueAddedTax / 100); // price with VAT return Math.round(priceWithVAT * 100) / 100.0; // round to kopecks }
- We now have four methods with the same name but different parameter sets.
Insert the appropriate overloaded method into the four branches of our cost calculation cycle.
if ("y".equalsIgnoreCase(includeVatResponse)) { // include VAT in cost if (amount >= 10) { // apply discount fullCost = getFullCost(unitCost, amount, DISCOUNT_FIVE, VALUE_ADDED_TAX); } else { // no discount fullCost = getFullCost(unitCost, amount, VALUE_ADDED_TAX); } } else { // do not include VAT in cost if (amount >= 10) { // apply discount fullCost = getFullCost(unitCost, amount, DISCOUNT_FIVE); } else { // no discount fullCost = getFullCost(unitCost, amount); } }
- Print the calculated cost to the console.
// Output the result of total cost calculation System.out.println("Total cost of the product = " + fullCost);
- Run the finished program.
Assignment
Assignment 1: GCD of Two Numbers
To do: Write a program that computes and displays the greatest common divisor (GCD) of two numbers.
Task Analysis
Input data:
int n1;// first numberint n2;// second number
Program variables:
int k;// counter
Output data:
int gcd;// GCD
Method:
public static int find_gcd(int n1, int n2) { int gcd, k; gcd = 1; // GCD initialized to 1 k = 1; // prospective GCD value ... }
Algorithm with refinements:
- Get the first number.
- Get the second number.
- Compute the GCD of the two numbers.
- Let GCD be 1.
- While both numbers are greater than or equal to the prospective GCD.
- If both numbers are divisible without remainder by the prospective GCD, then update GCD.
- Increment the prospective GCD by 1.
- Display the GCD of the two numbers.
File name: L10Assign1.java
Tasks for Independent Work
| Task | Description | Expected Output | File Name |
|---|---|---|---|
| Task 1 | Three numbers are entered, they are the lengths of the triangle’s three sides. Create a Perimeter function that calculates the perimeter of a triangle based on the lengths of its three sides.Note 1: Perimeter() method must accept three integers as arguments.Note 2: The method must return no value which is why you have to use void in the signature. |
Please enter the 3 sides of the triangle: 3 5 6 The perimeter is: 14 |
L10Task1.java |
| Task 2 | Modify the previous task. Now the Perimeter function must return an integer value. We remind you of the task: Three numbers are entered, they are the lengths of the triangle’s three sides. Create a Perimeter function that calculates the perimeter of a triangle based on the lengths of its three sides.Note 1: Perimeter() method must accept three integers as arguments.Note 2: The method must return an integer value which is why you have to use int in the signature. |
Please enter the 3 sides of the triangle: 3 5 6 The perimeter is: 14 |
L10Task2.java |
| Task 3 | Create a Distance function that calculates a distance between two points on the plane, the coordinates of the points are entered (the variables x1,y1 for the first point and x2,y2 for the second).Note 1: The Distance() method must accept four integers as arguments (the coordinates of the points).Note 2: The method must return no value which is why you have to use void in the signature: static void distance(...);Note 3: To calculate the distance between two points you have to use the formula: √((x2-x1)²+(y2-y1)²) // square root: Math.sqrt(double value);// the power of a number: Math.pow(double base, double exponent); |
Please enter the coordinates of two points (four integers: x1, y1, x2, y2): 1 -2 4 2 The distance is: 5 |
L10Task3.java |
| Task 4 | Modify the previous task. Now the distance function must return a double value. We remind you of the task: Create a distance function that calculates a distance between two points on the plane, the coordinates of the points are entered (variables x1,y1 for the first point and x2,y2 for the second).Note: The method must return a double value which is why you have to use double in the signature: static double distance(...); |
Please enter the coordinates of two points (four integers: x1, y1, x2, y2): 3.2 3.4 8 7.1 The distance is: 6.0605 |
L10Task4.java |
| Task 5 | A two-digit integer is entered. Create ChangeDigits() method that takes an entered argument and changes its value so that the first digit of a new number is the second digit of the input number, and vice versa, the second digit of a new number is the first digit of the input number. For example, if 45 is entered, the resulting number will be 54.Note 1: The changeDigits() method must take an integer as an argument.Note 2: The method returns int value: static int changeDigits(...); |
Please enter two-digit number: 58 The result is: 85 |
L10Task5.java |
| Task 6 | Two two-digit integers are entered. Create a bitwiseSum function that calculates their bitwise sum modulo 10. For example, the bitwise sum of the numbers 34 and 59 is the number 83 (3 + 5 = 8; 4 + 9 = 13, 13%10 = 3).Note 1: The bitwiseSum() method must take two integers as arguments.Note 2: The method must return an integer value which is why you have to use int in the signature: static int bitwiseSum(...); |
Please enter two two-digit numbers: 34 59 The bitwise sum of 34 and 59 is: 83 |
L10Task6.java |
| Task 7 | Create posNegSeq() method that takes no arguments, and it should count positive and negative values of the entered sequence. User must input the sequence of integers and finish the inputting by entering 0. The method has to count positive and negative of the entered numbers and return the values of counters to the main function.Note 1: The method returns counted values. |
Please enter the sequence, input 0 when it ends 2 -4 8 -3 5 0 counter for positive is: 3, counter for negative is: 2 |
L10Task7.java |
| Task 8 | Create a new project. Add a new class-file to the project. Create a method within this class to calculate the following sequence: 1 + A + A² + A³ + … + Aⁿ. A must be entered double number. N is entered integer greater than 0. You shouldn’t use a standard pow() method; to calculate the power of the numbers you should use loop. |
Enter A: 1.5 Enter N: 6 The sequence sum is: 32.171875 |
L10Task8.java |
Extra Tasks
Extra Task 1
To do: Create a FloorCubicRoot function that finds the largest integer that does not exceed the cubic root of the specified number (Math.pow, Math.floor).
Note: You can calculate the cubic root of the number x in the wolframalpha service using the query x^(1/3), for example: 15.625^(1/3) (the answer is 2.5).
Expected output:
15.625
The result is 2.5 : 15.625 ^ 1/3
File name: L10ExTask1.java
Extra Task 2
To do: A real number A and an integer N (≥ 0) are entered. Create a function SumOfSeq() which finds the sum of:
1 + A + A² + A³ + ... + Aⁿ
Note 1: Within a function, there has to be the only loop.
Note 2: Do not use standard pow function for the degree, accumulate the values of degrees using a loop.
Expected output:
2.2 3
Sum of elements of the sequence of powers of the number 2.2 from 0 to 3: 18.688
File name: L10ExTask2.java