重点内容概览
- 数组作为方法参数与返回值的使用
- 引用数据类型与基本数据类型的区别(值传递和引用传递)
- 排序算法(冒泡排序、选择排序)
- 数组拷贝与扩容
- Arrays 工具类的常用方法
一、数组去重示例(核心代码)
public class Main {
public static void main(String[] args) {
int[] arr = {0, 1, 1, 2, 3, 3, 5, 8, 9};
int[] temp = new int[arr.length];
int count = 0;
for (int i = 0; i < arr.length; i++) {
int current = arr[i];
boolean isDuplicate = false;
// 检查当前元素是否已存在于临时数组中
for (int j = 0; j < count; j++) {
if (temp[j] == current) {
isDuplicate = true;
break;
}
}
// 如果未重复,则添加到临时数组
if (!isDuplicate) {
temp[count++] = current;
}
}
// 创建结果数组并复制元素
int[] result = new int[count];
System.arraycopy(temp, 0, result, 0, count);
// 输出结果:0 1 2 3 5 8 9
for (int num : result) {
System.out.print(num + " ");
}
}
}
小结:
- 去重的核心思路是通过临时数组存储不重复元素,双重循环判断重复
- 时间复杂度为 O (n²),有更高效的方法(后续可以了解哈希表去重)
二、数组复习
-
数组特性
- 数组创建后长度不可改变
- 只能存储同一种数据类型
-
数组创建语法
- 指定长度:
int[] arr = new int[4]; - 指定元素:
int[] arr = new int[]{1,2,3};或int[] arr = {1,2,3};
- 指定长度:
-
数组操作
- 存值:
arr[0] = 1; - 取值:
int a = arr[0]; - 遍历:
for(int i = 0; i < arr.length; i++){ System.out.println(arr[i]); } - 长度属性:
arr.length
- 存值:
小结:
- 数组下标从 0 开始,注意避免数组越界异常(ArrayIndexOutOfBoundsException)
三、数组常用操作
package com.qf.homework;
public class Homework {
public static void main(String[] args) {
// printArr();
printIndex();
}
// 1. 遍历数组,拼接成[1,2,3,4]格式
public static void printArr() {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
String s = "[";
for (int i = 0; i < arr.length; i++) {
s += arr[i];
if (i != arr.length - 1) {
s += ",";
} else {
s += "]";
}
}
System.out.println(s);
}
// 2. 根据元素找下标,找到输出下标,找不到输出提示
public static void printIndex() {
int[] arr = {1, 1, 2, 2, 3, 3, 4};
int n = 5;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == n) {
System.out.println(n + "在数组中存在,下标是" + i);
return; // 找到后直接结束方法
}
}
System.out.println(n + "不存在于数组中");
}
// 3. 根据元素找下标,找到返回下标,找不到返回-1
public static int getIndex() {
int[] arr = {1, 1, 2, 2, 3, 3, 4};
int n = 5;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == n) {
return i;
}
}
return -1;
}
}
小结:
- 方法中使用
return可以提前结束方法执行,提高效率 - 字符串拼接在循环中效率较低,后续可以了解
StringBuilder
四、数组的应用(方法参数与返回值)
4.1 方法的四种类型
// 1. 无参无返回值
public static void show() {}
// 2. 有参无返回值
public static void show(int a, int b) {}
// 3. 无参有返回值
public static String show() {
return "hello world";
}
// 4. 有参有返回值
public static String show(String str) {
return str;
}
4.2 数组作为方法参数
package com.qf.a_array;
import java.util.Arrays;
public class Demo1 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
printArr(arr); // 传递数组引用
System.out.println(Arrays.toString(arr));
}
// 数组作为方法参数
public static void printArr(int[] arr) {
String s = "[";
for (int i = 0; i < arr.length; i++) {
s += arr[i];
if (i != arr.length - 1) {
s += ", ";
} else {
s += "]";
}
}
System.out.println(s);
}
}
4.3 数组作为方法返回值
package com.qf.a_array;
public class Demo2 {
public static void main(String[] args) {
int[] resultArr = getArray();
System.out.println("2)" + resultArr); // 打印数组地址
}
// 数组作为返回值
public static int[] getArray() {
int[] arr = new int[5];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
System.out.println("1)" + arr); // 打印数组地址
return arr;
}
}
4.4 数组反转实例
package com.qf.a_array;
import java.util.Arrays;
public class Demo3 {
public static void main(String[] args) {
int[] reverseArr = reverse(new int[]{1, 2, 3, 4});
System.out.println(Arrays.toString(reverseArr)); // [4,3,2,1]
}
public static int[] reverse(int[] arr) {
int[] newArr = new int[arr.length];
// 双指针法反转
for (int i = 0, j = arr.length - 1; i < arr.length; i++, j--) {
newArr[i] = arr[j];
}
return newArr;
}
}
思考记录区:
- 数组作为引用类型,传递的是地址值,方法内对数组的修改会影响原数组
- 数组反转可以通过双指针一次遍历完成,时间复杂度 O (n)
五、引用数据类型(核心概念)
5.1 数据类型分类
- 基本数据类型:四类八种(int, double, boolean 等)
- 引用数据类型:数组、类、接口等
5.2 核心区别
| 类型 | 存储位置 | 传递方式 | 特点 |
|---|---|---|---|
| 基本类型 | 栈内存 | 值传递 | 方法执行完变量消失 |
| 引用类型 | 堆内存 | 地址值传递 | 方法执行完对象仍在堆中 |
5.3 基本类型值传递示例
java
运行
public static void main(String[] args) {
int a = 1;
System.out.println("1) a = " + a); // 1
changeBaseValue(a);
System.out.println("4) a = " + a); // 1(值未改变)
}
public static void changeBaseValue(int a) {
System.out.println("2) a = " + a); // 1
a *= 10;
System.out.println("3) a = " + a); // 10
}
5.4 引用类型传递示例
package com.qf.a_array;
import java.util.Arrays;
public class Demo5 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4};
System.out.println("1)" + Arrays.toString(arr)); // [1,2,3,4]
changeRefValue(arr);
System.out.println("4)" + Arrays.toString(arr)); // [1,2,3,1000](值已改变)
}
private static void changeRefValue(int[] arr) {
System.out.println("2)" + Arrays.toString(arr)); // [1,2,3,4]
arr[3] = 1000;
System.out.println("3)" + Arrays.toString(arr)); // [1,2,3,1000]
}
}
思考记录区:
- 引用类型的 "传递" 本质是地址的传递,多个引用可以指向同一个对象
- 理解堆栈内存模型对掌握引用类型至关重要
六、排序算法(面试重点)
6.1 冒泡排序
核心思路:相邻元素两两比较,大的元素往后移(每轮确定一个最大值)
package com.qf.a_array;
import java.util.Arrays;
public class Demo6 {
public static void main(String[] args) {
int[] arr = {2, 4, 3, 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;
}
}
}
System.out.println(Arrays.toString(arr)); // [1,2,3,4]
}
}
6.2 选择排序
核心思路:每轮找到最小值下标,与当前位置交换(每轮确定一个最小值)
package com.qf.a_array;
import java.util.Arrays;
public class Demo7 {
public static void main(String[] args) {
int[] arr = {2, 4, 3, 1};
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i; // 假设当前位置是最小值
// 寻找最小值下标
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) {
minIndex = j;
}
}
// 交换元素
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
System.out.println(Arrays.toString(arr)); // [1,2,3,4]
}
}
6.3 JDK 自带排序
package com.qf.a_array;
import java.util.Arrays;
public class Demo8 {
public static void main(String[] args) {
int[] arr = {2, 4, 3, 1};
Arrays.sort(arr); // 升序排序
System.out.println(Arrays.toString(arr)); // [1,2,3,4]
}
}
思考记录区:
- 冒泡排序和选择排序的时间复杂度都是 O (n²)
- 选择排序交换次数更少,效率略高于冒泡排序
- 实际开发中优先使用 JDK 提供的
Arrays.sort()(底层是优化后的快速排序)
七、数组拷贝
7.1 手动拷贝
int[] arr = {89, 67, 23, 19};
int[] newArr = new int[arr.length * 2];
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
7.2 Arrays.copyOf()
int[] newArr2 = Arrays.copyOf(arr, arr.length * 2); // 参数:源数组,新数组长度
7.3 System.arraycopy()
int[] newArr3 = new int[arr.length * 2];
// 参数:源数组,源起始下标,目标数组,目标起始下标,拷贝长度
System.arraycopy(arr, 0, newArr3, 0, arr.length);
小结:
System.arraycopy()是 native 方法,效率最高(native方法是用非Java语言(通常是C/C++)编写的代码,直接编译成机器码执行)- 数组拷贝是浅拷贝,对于引用类型数组,拷贝的是地址值
八、数组扩容
原理:创建更大的新数组,拷贝原数组元素,使用新数组
package com.qf.array;
public class Demo5 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
System.out.println("扩容前arr: " + Arrays.toString(arr));
arr = changeSize(arr); // 接收新数组地址
System.out.println("扩容后arr: " + Arrays.toString(arr));
}
// 数组扩容(扩大1倍)
public static int[] changeSize(int[] a) {
int[] newArr = new int[a.length * 2];
System.arraycopy(a, 0, newArr, 0, a.length);
return newArr;
}
}
思考记录区:
- 数组本身不可扩容,"扩容" 是通过创建新数组实现的
- 频繁扩容会影响性能,应合理预估数组大小
九、Arrays 工具类常用方法
-
toString():数组转字符串
int[] arr = {1,2,3,4}; System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4] -
sort():数组排序(升序)
Arrays.sort(arr); -
copyOf():数组拷贝
int[] newArr = Arrays.copyOf(arr, arr.length);
思考记录区:
- Arrays 类的方法都是静态方法,需通过
Arrays.方法名()调用 toString()是调试数组的常用方法
十、总结
-
核心知识点
- 数组作为方法参数和返回值的使用
- 引用类型与基本类型的传递区别
- 冒泡排序和选择排序的实现原理
- 数组拷贝与扩容的实现方式
-
重点掌握
- 引用数据类型的内存模型(堆、栈)
- 排序算法的实现代码
- Arrays 工具类的常用方法
- 数组是线性表的基础,后续集合框架(如 ArrayList)底层就是基于数组实现的
- 理解引用类型是学习面向对象编程的基础
6663

被折叠的 条评论
为什么被折叠?



