2021-10-15 JAVA - use of methods

Posted by danwatt on Fri, 15 Oct 2021 23:36:02 +0200

1. Basic usage of the method

1.1 what is a method

A method is a code fragment. It is similar to the "function" in C language
Significance of method existence (don't recite, focus on experience):

  1. It is a modular organization code (when the code scale is complex)
  2. The code can be reused, and a code can be used in multiple locations
  3. Make the code easier to understand
  4. Directly call the existing methods for development, and there is no need to build wheels repeatedly
    Recall a previously written code: calculate 1+ 2! + 3! + 4! + 5!
int sum = 0;
for (int i = 1; i <= 5; i++) {
  int tmp = 1;
  for (int j = 1; j <= i; j++) {
    tmp *= j;
 }
  sum += tmp;
}
System.out.println("sum = " + sum);

Double loop is used in this code, which is easy to make mistakes. Next, we can use methods to optimize this code

1.2 method definition syntax

Basic grammar

// Method definition
public static Method return value method name([Parameter type parameter ...]){
Method body code;
[return Return value];
}
// Method call
 Return value variable = Method name(Argument...);

Code example: implement a method to add two integers

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        // Method call
        int ret = add(a, b);
        System.out.println("ret = " + ret);
}
  // Definition of method
public static int add(int x, int y) {
    return x + y;
    }
}
// results of enforcement
ret = 30

matters needing attention

  1. The public and static keywords have specific meanings here. We won't discuss them for the time being. They will be described in detail later
  2. When a method is defined, the parameters may not be. Each parameter must specify a type
  3. When defining a method, the return value can also be null. If there is no return value, the return value type should be written as void
  4. The parameters when a method is defined are called "formal parameters", and the parameters when a method is called are called "arguments"
  5. The method definition must be in the class, and the code can be written above or below the calling position
  6. There is no concept of "function declaration" in Java

1.3 execution process of method call

Basic rules

  • When defining a method, the code of the method will not be executed. It will only be executed when calling
  • When the method is called, the argument is assigned to the formal parameter
  • After the parameter is passed, it will be executed to the method body code
  • When the method is executed (encounter the return statement), it is executed. Return to the method call position and continue to execute
  • A method can be called multiple times

1.4 relationship between arguments and formal parameters (important)

Code example: exchanging two integer variables

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a, b);
        System.out.println("a = " + a + " b = " + b);
        }
    public static void swap(int x, int y) {
        int tmp = x;
        x = y;
        y = tmp;
    }
}
// Operation results
a = 10 b = 20

Cause analysis
The code just now did not complete the data exchange
For the basic type, the formal parameter is equivalent to a copy of the argument, that is, a value passing call

int a = 10;
int b = 20;
int x = a;
int y = b;
int tmp = x;
x = y;
y = tmp;

As you can see, the modifications to x and y do not affect a and b
Solution: pass reference type parameters (such as array to solve this problem)
The running process of this code will be explained in detail later when learning arrays

class Test {
    public static void main(String[] args) {
        int[] arr = {10, 20};
        swap(arr);
        System.out.println("a = " + arr[0] + " b = " + arr[1]);
    }
    public static void swap(int[] arr) {
        int tmp = arr[0];
        arr[0] = arr[1];
        arr[1] = tmp;
    }
}
// Operation results
a = 20 b = 10

1.5 methods without return value

The return value of the method is optional. It may not be available sometimes
Code example

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        print(a, b);
    }
    public static void print(int x, int y) {
        System.out.println("x = " + x + " y = " + y);
    }
}

In addition, the method of exchanging two integers just now has no return value

2. Overloading of methods

Sometimes we need to use a function compatible with multiple parameters at the same time, we can use method overloading

2.1 problems to be solved by heavy load

Code example

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = add(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int add(int x, int y) {
        return x + y;
    }
}
// Compilation error
Test.java:13: error: Incompatible types: from double Convert to int There may be losses
        double ret2 = add(a2, b2);
                 ^

The existing add method cannot be used directly because the parameter types do not match
So should you create such code?
Code example

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = addInt(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = addDouble(a2, b2);
        System.out.println("ret2 = " + ret2);
    }
    public static int addInt(int x, int y) {
        return x + y;
}
    public static double addDouble(double x, double y) {
        return x + y;
    }
}

This is correct (for example, Go language does this), but Java thinks that the name addInt is unfriendly, so it's better to call it add directly

2.2 use heavy load

Code example

class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = add(a2, b2);
        System.out.println("ret2 = " + ret2);
        double a3 = 10.5;
        double b3 = 10.5;
        double c3 = 20.5;
        double ret3 = add(a3, b3, c3);
        System.out.println("ret3 = " + ret3);
    }
    public static int add(int x, int y) {
        return x + y;
    }
    public static double add(double x, double y) {
        return x + y;
}
    public static double add(double x, double y, double z) {
        return x + y + z;
    }
}

The names of methods are all called add. However, some add calculates the addition of int, some double, some two numbers, and some three numbers. The same method name provides different versions of implementation, which is called method overloading

2.3 overload rules

For the same class:

  • Same method name
  • Method has different parameters (number of parameters or parameter type)
  • The return value type of the method does not affect overloading
class Test {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
    }
    public static int add(int x, int y) {
        return x + y;
    }
    public static double add(int x, int y) {
        return x + y;
    }
}
// Compilation error
Test.java:13: error: Already in class Test Methods are defined in add(int,int)
    public static double add(int x, int y) {
              ^
1 Errors

When two methods have the same name and parameters, but the return values are different, they do not constitute an overload

3. Method recursion

3.1 concept of recursion

When a method calls itself in the process of execution, it is called "recursion". Recursion is equivalent to mathematical induction. It has a starting condition and then a recurrence formula.
For example, when we find N! Starting condition: N = 1, N! Is 1. This starting condition is equivalent to the end condition of recursion. Recursion formula: find N!, it is not easy to find directly, and the problem can be converted into N! = > N * (N-1)!
Code example: recursively find the factorial of N

public static void main(String[] args) {
    int n = 5;
    int ret = factor(n);
    System.out.println("ret = " + ret);
}
public static int factor(int n) {
    if (n == 1) {
        return 1;
    }
    return n * factor(n - 1); // factor calls the function itself
}
// results of enforcement
ret = 120
public static void main(String[] args) {
    int n = 5;
    int ret = factor(n);
    System.out.println("ret = " + ret);
}

3.2 recursive execution process analysis

The execution process of recursive programs is not easy to understand. To understand recursion clearly, you must first understand the "method execution process", especially "after the method execution is completed, return to the calling position and continue to execute"
Code example: recursively find the factorial of N, plus the log version

public static void main(String[] args) {
    int n = 5;
    int ret = factor(n);
    System.out.println("ret = " + ret);
}
public static int factor(int n) {
    System.out.println("Function start, n = " + n);
    if (n == 1) {
        System.out.println("End of function, n = 1 ret = 1");
        return 1;
    }
    int ret = n * factor(n - 1);
    System.out.println("End of function, n = " + n + " ret = " + ret);
    return ret;
}
// results of enforcement
 Function start, n = 5
 Function start, n = 4
 Function start, n = 3
 Function start, n = 2
 Function start, n = 1
 End of function, n = 1 ret = 1
 End of function, n = 2 ret = 2
 End of function, n = 3 ret = 6
 End of function, n = 4 ret = 24
 End of function, n = 5 ret = 120
ret = 12

Execution process diagram

The program is executed in the order of (1) - > (8) identified in the serial number
About "call stack"
When a method is called, there will be a memory space such as "stack" to describe the current call relationship. It is called call stack
Each method call is called a "stack frame". Each stack frame contains the parameters of the call, where to return and continue execution
Later, we can easily see the contents of the call stack with the help of IDEA

3.3 recursive exercise

Code example 1 prints each bit of a number in sequence (for example, 1234 prints 1 2 3 4)

public static void print(int num) {
    if (num > 9) {
        print(num / 10);
    }
    System.out.println(num % 10);
}

Code example 2 recursively find 1 + 2 + 3 +... + 10

public static int sum(int num) {
    if (num == 1) {
        return 1;
    }
    return num + sum(num - 1);
}

Code example 3 writes a recursive method, enters a non negative integer and returns the sum of the numbers that make up it. For example, if you enter 1729, you should return 1 + 7 + 2 + 9, and its sum is 19

public static int sum(int num) {
    if (num < 10) {
        return num;
    }
    return num % 10 + sum(num / 10);
}

Code example 4 find the nth item of Fibonacci sequence
Fibonacci sequence introduction: https://baike.sogou.com/v267267.htm?fromTitle=%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97

public static int fib(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return fib(n - 1) + fib(n - 2);
}

When we calculate fib(40), we find that the execution speed of the program is very slow. The reason is that a large number of repeated operations are carried out

class Test {
    public static int count = 0; // This is the member variable of the class. It will be described in detail later
    public static void main(String[] args) {
    System.out.println(fib(40));
    System.out.println(count);
    }
    public static int fib(int n) {
        if (n == 1 || n == 2) {
            return 1;
        }
        if (n == 3) {
            count++;
        }
        return fib(n - 1) + fib(n - 2);
    }
}
// results of enforcement
102334155
39088169 // fib(3) was repeated 30 million times

The Fibonacci sequence problem can be solved in a circular way to avoid redundant operations

public static int fib(int n) {
    int last2 = 1;
    int last1 = 1;
    int cur = 0;
    for (int i = 3; i <= n; i++) {
        cur = last1 + last2;
        last2 = last1;
        last1 = cur;
    }
    return cur;
}

At this time, the execution efficiency of the program is greatly improved
Code example 5 solve the Hanoi Tower problem (prompt, use recursion)
The tower of Hanoi problem is a classical problem. The Hanoi Tower, also known as the river tower, originates from an ancient Indian legend. When Brahma created the world, he made three diamond pillars. On one pillar, 64 gold discs were stacked in order of size from bottom to top. Brahma ordered Brahman to rearrange the disk on another column in order of size from below. It is also stipulated that the disc cannot be enlarged on the small disc at any time, and only one disc can be moved between the three columns at a time. How should I operate?

import java.util.Scanner;
//The Hanoi Tower problem uses recursion to realize the Hanoi Tower problem. The code is as follows:
public class Move {
    public static void moveDish(int level, char from, char inter, char to) {
        if (level == 1) {// If there is only one plate, exit the iteration
            System.out.println("from " + from + " Move plate 1 to " + to);
        } else {// If there is more than one plate, continue the iteration
            moveDish(level - 1, from, to, inter);
            System.out.println("from " + from + " Moving plate " + level + " No. to " + to);
            moveDish(level - 1, inter, from, to);
        }
    }

    public static void main(String[] args) {
        System.out.println("Please enter the number of floors of Hanoi Tower:");
        Scanner scanner = new Scanner(System.in);
        Integer n = scanner.nextInt();// Set Hanoi tower to level 3
        //int nDisks = 3;
        moveDish(n, 'A', 'B', 'C');// Implement mobile algorithm
    }
}

Code example 6 frog jumping steps (prompt, using recursion)
A frog can jump up one step or two steps at a time. How many jumping methods does the frog jump up an n-step

public class Frog{
    //Implementation code: frog jumping steps (prompt, use recursion) a frog can jump up one step or two steps at a time.
    // How many jumping methods does the frog jump up an n-step

    //1. We first consider the end condition of this problem, that is, when there are only 1 or 2 steps left, the recursion can end
    //2. It can be seen from the title that frogs can jump one step or two steps at a time, so the possibility of a total of steps n can be listed by the possibility function relationship between - 1 and - 2 each time
    // That is, f(n) = f(n - 1) + f(n -2);
    public static void main(String[] args) {
        System.out.println(JumpFloor(5));
    }
    public static int JumpFloor(int a) {
        if (a == 1) {
            return 1;
        } else if (a == 2) {
            return 2;
        }else {
            return JumpFloor(a - 1) + JumpFloor(a - 2);
        }
    }
}

3.4 recursive summary
Recursion is an important way to solve programming problems
Some problems are naturally defined recursively (such as Fibonacci sequence, binary tree, etc.), so it is easy to use recursive solutions
Some problems can be solved by using recursion and non recursion (loop). It is more recommended to use loop at this time. Compared with recursion, non recursive programs are more efficient

Topics: Java