课前回顾

  • 数组作用:一次存储多个数据。
  • 数组特点:定长;可存储基本类型和引用类型。
  • 数组定义
    • 动态初始化:数据类型[] 数组名 = new 数据类型[长度]
    • 静态初始化:数据类型[] 数组名 = {元素1, 元素2, ...}
  • 获取长度数组名.length
  • 索引:从 0 开始,最大索引为长度-1,唯一。
  • 存取元素数组名[索引] = 值(存),数组名[索引](取)。
  • 遍历数组名.fori(IDEA 快捷方式)。
  • 常见异常
    • ArrayIndexOutOfBoundsException:索引越界。
    • NullPointerException:引用为 null 却操作它。

今日重点

  • 手写冒泡排序、二分查找
  • 使用 Arrays 数组工具类
  • 操作二维数组(定义、存取、遍历)
  • 方法的使用(无参/有参,无返回值/有返回值)

重要提示:今天如果方法的定义和调用不熟练,请优先练习方法,其他知识点可以稍后。


第一章 数组常见算法

1. 数组翻转

概述:将数组中对称位置上的元素互换。

public class Demo01ArrayReverse {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        for (int min = 0, max = arr.length - 1; min < max; min++, max--) {
            int temp = arr[min];
            arr[min] = arr[max];
            arr[max] = temp;
        }
        // 输出翻转后的数组
        for (int i : arr) {
            System.out.print(i + " ");  // 5 4 3 2 1
        }
    }
}

2. 冒泡排序

概述:相邻元素两两比较,大的往后移,小的往前移(升序)。

核心思想:每轮将最大的元素“冒泡”到末尾。

public class Demo02Bubble {
    public static void main(String[] args) {
        int[] arr = {5, 4, 3, 2, 1};
        // 外层循环控制比较的轮数
        for (int i = 0; i < arr.length - 1; i++) {
            // 内层循环控制每轮比较的次数
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        // 输出排序结果
        for (int num : arr) {
            System.out.print(num + " ");  // 1 2 3 4 5
        }
    }
}

3. 二分查找

概述:每次取中间索引比较,每次排除一半数据。
前提:数组必须有序(默认升序)。

public class Demo03BinarySearch {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int min = 0;
        int max = arr.length - 1;
        int key = 10;  // 要查找的值
        while (min <= max) {
            int mid = (min + max) / 2;
            if (key > arr[mid]) {
                min = mid + 1;
            } else if (key < arr[mid]) {
                max = mid - 1;
            } else {
                System.out.println("找到了,索引是:" + mid);
                break;
            }
        }
    }
}

第二章 数组工具类

1. System 类

  • 系统相关类,方法直接用类名调用。
  • 常用方法:arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
int[] arr2 = new int[10];
System.arraycopy(arr, 0, arr2, 0, arr.length);
System.out.println(Arrays.toString(arr2)); // [1, 2, 3, 4, 5, 6, 7, 8, 0, 0]

2. Arrays 类

方法说明
String toString(数组)[元素1, 元素2, ...] 格式打印
void sort(数组)升序排序
int binarySearch(数组, 要查找的元素)二分查找,返回索引
int[] copyOf(数组, 新长度)数组扩容,返回新数组
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println(Arrays.toString(arr));

int[] arr2 = {5, 4, 3, 2, 1};
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));

int index = Arrays.binarySearch(arr, 3);
System.out.println(index); // 2

int[] newArr = Arrays.copyOf(arr2, 10);
System.out.println(Arrays.toString(newArr));

3. Hutool 工具(第三方)

官网:https://www.hutool.cn/

引入 jar 包步骤(IDEA)

  1. 模块下新建 lib 目录
  2. 复制 hutool 的 jar 包到 lib 下
  3. 右键 lib → Add as Library → 选择 Module

ArrayUtil 常用方法

方法说明
int max(数组)返回数组最大值
int indexOf(数组, 要查找的数据)顺序查找,返回索引
reverse(数组)数组翻转
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
System.out.println(ArrayUtil.max(arr));      // 8
System.out.println(ArrayUtil.indexOf(arr, 3)); // 2
ArrayUtil.reverse(arr);
System.out.println(ArrayUtil.toString(arr)); // [8, 7, 6, 5, 4, 3, 2, 1]

第三章 二维数组

1. 定义格式

动态初始化

数据类型[][] 数组名 = new 数据类型[m][n];  // m:二维数组长度,n:每个一维数组长度

静态初始化

数据类型[][] 数组名 = {{元素1, 元素2, ...}, {元素1, 元素2, ...}, ...};

示例:

int[][] arr1 = new int[3][3];
int[][] arr2 = new int[3][];   // 一维数组暂未创建
int[][] arr3 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
String[][] arr4 = {{"唐僧", "孙悟空", "猪八戒"}, {"刘备", "关羽"}, {"金莲", "涛哥"}};

2. 获取长度

int[][] arr = new int[3][3];
System.out.println(arr.length);          // 3
System.out.println(arr[0].length);       // 3

3. 存取元素

String[][] arr = {{"唐僧", "孙悟空", "猪八戒"}, {"刘备", "关羽"}, {"金莲", "涛哥"}};
System.out.println(arr[0][0]);  // 唐僧
System.out.println(arr[1][1]);  // 关羽
System.out.println(arr[2][1]);  // 涛哥

arr[0][0] = "唐三藏";

4. 遍历二维数组

for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr[i].length; j++) {
        System.out.println(arr[i][j]);
    }
}

第四章 方法的使用

方法通用定义格式

修饰符 返回值类型 方法名(参数) {
    方法体
    return 结果;
}

1. 无参无返回值

public static void 方法名() {
    // 方法体
}
// 调用:方法名();

示例:

public static void add() {
    int a = 10, b = 20;
    System.out.println(a + b);
}
// 调用 add();

2. 有参无返回值

public static void 方法名(参数) {
    // 方法体
}
// 调用:方法名(实参);

示例:

public static void add(int a, int b) {
    System.out.println(a + b);
}
// 调用 add(10, 20);

3. 无参有返回值

public static 返回值类型 方法名() {
    // 方法体
    return 结果;
}
// 调用:数据类型 变量名 = 方法名();  或 System.out.println(方法名());

示例:

public static int add() {
    int a = 10, b = 20;
    return a + b;
}
// 调用 int sum = add();

4. 有参有返回值

public static 返回值类型 方法名(参数) {
    // 方法体
    return 结果;
}
// 调用:数据类型 变量名 = 方法名(实参);

示例:

public static int add(int a, int b) {
    return a + b;
}
// 调用 int sum = add(10, 20);

形参与实参

  • 形参:定义方法时的参数,无具体值。
  • 实参:调用方法时传递给形参的具体值。

参数和返回值使用时机

  • 参数:需要将数据从调用者传入方法内部时使用。
  • 返回值:方法执行后需要将结果返回给调用者时使用。

第五章 方法进阶

方法注意事项

  1. 方法不调用不执行。
  2. 执行顺序只与调用顺序有关。
  3. void 不能与 return 结果 共存,但可以与 return(仅结束方法)共存。
  4. 调用方法时,方法名、参数个数、类型、顺序必须完全一致。
  5. 一个方法只能有一个返回值(if-else 除外)。

方法练习

练习 1:判断奇偶性

public static String judge(int num) {
    return num % 2 == 0 ? "偶数" : "奇数";
}

练习 2:1~100 求和

public static int sum100() {
    int sum = 0;
    for (int i = 1; i <= 100; i++) sum += i;
    return sum;
}

练习 3:循环打印

public static void print(int n) {
    for (int i = 0; i < n; i++) {
        System.out.println("我是一个有经验的 Java+智能体开发工程师");
    }
}

练习 4:遍历数组

public static void printArray(int[] arr) {
    System.out.println(Arrays.toString(arr));
}

练习 5:求数组最大值(自行练习)

练习 6:按指定格式输出数组(自行练习)

练习 7:数组作为返回值

public static int[] getSumAndSub(int a, int b) {
    int sum = a + b;
    int sub = a - b;
    return new int[]{sum, sub};
}

第六章 方法参数传递

  • 基本类型:传递的是值,不影响原变量。
  • 引用类型:传递的是地址值,会影响原数组/对象。

示例:

// 基本类型
public static void change(int a) { a = 100; }  // 外部不变

// 引用类型
public static void change(int[] arr) { arr[0] = 100; } // 外部数组改变

第七章 方法重载(Overload)

定义:同一个类中,方法名相同,参数列表不同。

参数列表不同

  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同

与返回值和参数名无关

示例:

public static void open() {}
public static void open(int a) {}
public static void open(int a, int b) {}
public static void open(double a, int b) {}
public static void open(int a, double b) {}

第八章 可变参数

格式数据类型...变量名
本质:数组
注意:一个方法只能有一个可变参数,且必须放在最后。

public static void sum(int... arr) {
    int sum = 0;
    for (int num : arr) sum += num;
    System.out.println(sum);
}
// 调用 sum(1, 2, 3, 4);

练习:字符串拼接

// 无分隔符
public static String concat(String... strs) {
    String result = "";
    for (String s : strs) result += s;
    return result;
}

// 带分隔符
public static String concat(String separator, String... strs) {
    if (strs.length == 0) return "";
    StringBuilder sb = new StringBuilder(strs[0]);
    for (int i = 1; i < strs.length; i++) {
        sb.append(separator).append(strs[i]);
    }
    return sb.toString();
}

第九章 递归

概述:方法内部调用自身。
注意:必须有出口,否则栈内存溢出。

示例 1:输出 3 到 1

public static void print(int n) {
    if (n == 0) return;
    System.out.println(n);
    print(n - 1);
}

示例 2:求 n!

public static int factorial(int n) {
    if (n == 1) return 1;
    return n * factorial(n - 1);
}

示例 3:斐波那契数列(不死神兔)

// 第 n 个月兔子对数
public static int fib(int n) {
    if (n == 1 || n == 2) return 1;
    return fib(n - 1) + fib(n - 2);
}
// 一年内:fib(12) = 144

第十章 面向对象基础

1. 面向对象思想

  • 是什么:Java 的核心编程思想。
  • 作用:减少代码量,提高复用性。
  • 使用方式
    • new 对象,然后 . 调用成员(如 Scanner、Random)
    • 类名直接调用静态成员

2. 类(实体类)

属性(成员变量):定义在类中方法外,有默认值。
行为(成员方法):去掉 static 关键字。

public class Person {
    // 属性
    String name;   // 默认 null
    int age;       // 默认 0

    // 行为
    public void eat() {
        System.out.println("吃饭");
    }
}

3. 对象的使用

  • 导包:同包下无需导包,不同包需 import
  • 创建对象类名 对象名 = new 类名()
  • 调用成员对象名.属性名 / 对象名.方法名()
Person p = new Person();
p.name = "张三";
p.age = 18;
p.eat();

4. 匿名对象

定义:没有名字的对象,即 new 类名().成员
使用场景:只需调用一次方法时。

new Person().eat();  // 不推荐用于赋值

第十一章 成员变量与局部变量区别

区别点成员变量局部变量
定义位置类中方法外方法内或形参
默认值有默认值无,必须手动赋值
作用范围整个类所在方法内
内存位置堆内存栈内存
生命周期随对象创建/销毁随方法调用/结束

第十二章 封装(private)

封装概述

隐藏实现细节,对外提供公共访问方式。
关键字private(私有,只能在本类中访问)

使用步骤

  1. 属性用 private 修饰
  2. 提供公共的 getXxx() / setXxx() 方法
public class Person {
    private String name;
    private int age;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setAge(int age) {
        if (age >= 0 && age <= 120) {
            this.age = age;
        }
    }
    public int getAge() {
        return age;
    }
}

this 关键字

  • 代表当前对象(调用该方法的对象)
  • 用于区分成员变量和局部变量(this.成员

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐