四、递归
4.1 递归概念
递归:方法调用自身的一种编程技巧,用于解决可以分解为相同子问题的问题。
递归要素:
基线条件:停止递归的条件
递归条件:调用自身的条件
4.2 经典递归示例
public class RecursionDemo {
// 1. 阶乘
public long factorial(int n) {
// 基线条件
if (n <= 1) {
return 1;
}
// 递归条件
return n * factorial(n - 1);
}
// 2. 斐波那契数列
public long fibonacci(int n) {
if (n <= 1) {
return n;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
// 3. 汉诺塔
public void hanoi(int n, char from, char to, char aux) {
if (n == 1) {
System.out.println("移动盘子 1 从 " + from + " 到 " + to);
return;
}
hanoi(n - 1, from, aux, to);
System.out.println("移动盘子 " + n + " 从 " + from + " 到 " + to);
hanoi(n - 1, aux, to, from);
}
// 4. 二分查找(递归实现)
public int binarySearch(int[] arr, int target, int left, int right) {
if (left > right) {
return -1;
}
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] > target) {
return binarySearch(arr, target, left, mid - 1);
} else {
return binarySearch(arr, target, mid + 1, right);
}
}
// 5. 目录遍历
public void listFiles(File dir, int level) {
File[] files = dir.listFiles();
if (files == null) return;
String indent = " ".repeat(level);
for (File file : files) {
System.out.println(indent + file.getName());
if (file.isDirectory()) {
listFiles(file, level + 1);
}
}
}
}
4.3 递归优化:尾递归与记忆化
public class RecursionOptimization {
// 1. 尾递归优化(Java未原生支持,但可改写)
public long factorialTailRec(int n, long accumulator) {
if (n <= 1) {
return accumulator;
}
return factorialTailRec(n - 1, n * accumulator);
}
// 2. 记忆化递归(缓存中间结果)
private Map<Integer, Long> memo = new HashMap<>();
public long fibonacciMemo(int n) {
if (n <= 1) return n;
if (memo.containsKey(n)) {
return memo.get(n);
}
long result = fibonacciMemo(n - 1) + fibonacciMemo(n - 2);
memo.put(n, result);
return result;
}
// 3. 递归转迭代
public long fibonacciIterative(int n) {
if (n <= 1) return n;
long prev2 = 0, prev1 = 1;
for (int i = 2; i <= n; i++) {
long current = prev1 + prev2;
prev2 = prev1;
prev1 = current;
}
return prev1;
}
}
五、静态方法
5.1 静态方法特性
public class StaticMethodDemo {
private int instanceVar = 10;
private static int staticVar = 20;
// 静态方法
public static void staticMethod() {
// 可以访问静态变量
System.out.println(staticVar);
// 不能直接访问实例变量(需要对象)
// System.out.println(instanceVar); // 编译错误
// 可以调用其他静态方法
anotherStaticMethod();
// 不能直接调用实例方法
// instanceMethod(); // 编译错误
}
public static void anotherStaticMethod() {
System.out.println("另一个静态方法");
}
// 实例方法
public void instanceMethod() {
// 可以访问静态变量
System.out.println(staticVar);
// 可以访问实例变量
System.out.println(instanceVar);
// 可以调用静态方法
staticMethod();
// 可以调用其他实例方法
anotherInstanceMethod();
}
public void anotherInstanceMethod() {
System.out.println("另一个实例方法");
}
// 静态代码块(类加载时执行)
static {
System.out.println("静态代码块执行");
staticVar = 100;
}
}
5.2 静态方法的使用场景
public class StaticMethodUsage {
// 1. 工具方法
public static class MathUtils {
public static int max(int a, int b) {
return a > b ? a : b;
}
public static boolean isEven(int num) {
return num % 2 == 0;
}
}
// 2. 工厂方法
public static class Person {
private String name;
private int age;
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public static Person of(String name, int age) {
return new Person(name, age);
}
public static Person fromMap(Map<String, Object> map) {
return new Person(
(String) map.get("name"),
(Integer) map.get("age")
);
}
}
// 3. 单例模式
public static class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// 4. main方法
public static void main(String[] args) {
int max = MathUtils.max(10, 20);
Person person = Person.of("张三", 25);
}
}
六、实例方法
6.1 实例方法特性
public class InstanceMethodDemo {
private String name;
private static int count;
public InstanceMethodDemo(String name) {
this.name = name;
count++;
}
// 实例方法可以访问实例变量和静态变量
public String getName() {
return this.name; // 可以使用this
}
public void setName(String name) {
this.name = name; // this区分成员变量和参数
}
// 实例方法可以调用其他实例方法和静态方法
public void doSomething() {
System.out.println(getName()); // 调用实例方法
System.out.println(getCount()); // 调用静态方法
helper(); // 调用私有实例方法
}
private void helper() {
System.out.println("私有辅助方法");
}
public static int getCount() {
return count;
}
}
6.2 this关键字
public class ThisDemo {
private String name;
private int age;
// 1. 区分成员变量和参数
public ThisDemo(String name, int age) {
this.name = name;
this.age = age;
}
// 2. 调用本类的其他构造器
public ThisDemo(String name) {
this(name, 0); // 调用上面的构造器
}
// 3. 返回当前对象(链式调用)
public ThisDemo setName(String name) {
this.name = name;
return this;
}
public ThisDemo setAge(int age) {
this.age = age;
return this;
}
// 链式调用示例
public void demo() {
ThisDemo demo = new ThisDemo("初始")
.setName("新名字")
.setAge(25);
}
// 4. 将当前对象作为参数传递
public void register() {
Registry.add(this); // 将当前对象传入
}
// 5. 内部类中访问外部类实例
class Inner {
public void display() {
// 访问外部类的this
System.out.println(ThisDemo.this.name);
}
}
}