Java 学习笔记:数组、方法与面向对象
·
课前回顾
- 数组作用:一次存储多个数据。
- 数组特点:定长;可存储基本类型和引用类型。
- 数组定义:
- 动态初始化:
数据类型[] 数组名 = 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)
- 模块下新建
lib目录 - 复制 hutool 的 jar 包到 lib 下
- 右键 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);
形参与实参
- 形参:定义方法时的参数,无具体值。
- 实参:调用方法时传递给形参的具体值。
参数和返回值使用时机
- 参数:需要将数据从调用者传入方法内部时使用。
- 返回值:方法执行后需要将结果返回给调用者时使用。
第五章 方法进阶
方法注意事项
- 方法不调用不执行。
- 执行顺序只与调用顺序有关。
void不能与return 结果共存,但可以与return(仅结束方法)共存。- 调用方法时,方法名、参数个数、类型、顺序必须完全一致。
- 一个方法只能有一个返回值(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(私有,只能在本类中访问)
使用步骤
- 属性用
private修饰 - 提供公共的
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.成员)
更多推荐



所有评论(0)