一维数组
数组一旦创建,大小是固定的。通过数组引用变量和下标来访问数组中的元素。
double[] myList = new double[10];
一个数组变量实际存储着申请这部分数组存储空间的引用但一般可以直接说是数组。
数组的大小要在创建数组的时候确定下来且一旦确定不可更改。
创建数组后,其元素被赋予默认值,数值型基本数据类型的默认值为0,char型的默认值为'\u0000', boolean型的默认之为false
数组初始化 - 声明、创建和初始化都放在一条语句之中
数组的声明、创建和初始化分开导致语法错误!!!
两种初始化语法:
// 第一种数组初始化在数组大小确定而数组元素为止的情况下 double[] myList01 = new double[3] myList01[0] = 1.1; myList01[1] = 1.2; myList01[2] = 1.3; // 第二种数组元素确定的情况下 double[] myList02 = {1.1, 1.2, 1.3}
对于char[]类型的数组可以使用一条打印语句打印
char[] city = {'J', 'i', 'a', 'n', 'g'}; System.out.println(city); // Jiang
示例 - 找出最大元素的最小下标值
int[] arr = {1, 2, 3, 4, 5, 99, 6, 7, 9}; int indexOfArr = 0; int max = arr[0]; for(int i = 1; i < arr.length; i++){ if(arr[i] > max){ max = arr[i]; indexOfArr = i; } } System.out.println("最大值的下标: " + indexOfArr + ",其值为: " + arr[indexOfArr]); // 最大值的下标: 5,其值为: 99
示例 - 随机打乱数组中的元素 🍎 🍎 🍎
int[] data = {2, 4, 6, 1, 3, 5}; System.out.println("Math.random(): " + Math.random()); for(int i = data.length - 1; i > 0; i--){ // Generate an index j randomly with 0 <= j <= i ==> j ∈ (0 + (int)(Math.random() * (i+1)) int j = (int)(Math.random() * (i + 1)); // Swap myList[i] with myList[j] 之所以打乱之后没有重复因为此时数组元素发生了调换 int temp = data[i]; data[i] = data[j]; data[j] = temp; } System.out.println(Arrays.toString(data)); // [4, 1, 6, 5, 3, 2]
数组的创建中会基于默认值
eg: int[] arr01 = new int[10]; // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
eg: String[] arr02 = new String[5]; // [null, null, null, null, null]
数组的复制
将一个数组中的内容复制到另外一个中,将数组的每个元素复制到另外一个数组中。
复制数组的三种方法:
1. for循环依次迭代逐个地复制数组的元素。
int[] sourceArray = {1, 2, 3, 4, 5}; int[] targetArray = new int[sourceArray.length]; for(int i = 0; i < sourceArray.length; i++){ targetArray[i] = sourceArray[i]; }
2. 使用System类中的静态方法arraycopy。
使用arraycopy的这个方法仍然需要手动的给目标数组(targetArray)分配内存空间
System.arraycopy(sourceArray, startIndex, targetArray, startIndex, copyLength);
3. 使用clone方法复制数组。
数组引用 - myList作为数组引用本质上只是一个指向堆内存空间的指针。
int[] myList; myList = new int[10]; myList = new int[20]; System.out.println("myList.length: " + myList.length); // myList.length: 20
Java中的值传递(pass-by-value)实际上是共享信息传递(pass-by-sharing)
- 对基本类型参数,传递的是实参的值(基本类型传递的是值或称为字面量)
- 对引用类型参数,传递的是堆内存空间的引用,给方法传递的是这个引用。
最好的描述 ===》 参数传递的是共享信息(pass-by-sharing) 。
"pass-by-value" explained by myself: Java中的值传递实质是栈值传递 - 对基本数据类型而言, 栈值指的是基本类型的字面量(值)。 - 对引用数据类型而言, 栈值指的是引用类型的栈引用(栈引用指向对应的堆内存空间)。
JVM将对象存储在堆(Heap)的内存区域之中,堆用于动态内存分配。(Dynamic memory allocation)
从方法中返回数组◀
数组的引用即可以作为参数变量传入方法中也可以以返回值的形式返回
示例: 🌈数组元素逆转
// reverse an array with int type(第一种在原始数组堆内存空间之上逆转) public static int[] reverseArrayVersion1(int[] array){ for(int i = 0; i < (array.length / 2); i++){ array[i] = array[i] + array[array.length - 1 - i]; array[array.length - 1 - i] = array[i] - array[array.length - 1 - i]; array[i] = array[i] - array[array.length - 1 - i]; } return array; } // reverse an array with in type (第二种将原始数组中内容逆序取出放入新的数组之中) public static int[] reverseArrayVersion2(int[] array){ int[] res Arr = new int[array.length]; for(int i = 0, j = array.length - 1; i < array.length; i++, j--){ resArr[i] = array[j]; } return resArr; }
可变参数列表(Variable length parameter list)
具有同样类型的可变长度的参数可以传递给方法,并将其作为数组对待。
当用数目可变的参数调用方法时,Java会创建一个数组并把参数传给它。
public class VarArgsDemo { public static void main(String[] args) { printMax(1, 2, 3, 4, 5); // The max value is: 5.0 printMax(new double[]{6, 7, 8, 9, 10}); // The max value is: 10.0 } private static void printMax(double...numbers){ if(numbers.length == 0){ System.out.println("No argument passed!"); return; // 表示当前函数终止运行出栈 } double result = numbers[0]; for(int i = 1; i < numbers.length; i++){ if(numbers[i] > result){ result = numbers[i]; } } System.out.println("The max value is: " + result); } }
在实际开发中最好不要使用可变数组;一个方法参数列表要明确(对同类型的数据来说: 参数个数明确的用指定形参代替,参数个数不明确的用同类型数组代替)
可边长参数的错误使用方法
总结: 一个参数列表之中只能出现一个可变长参数如何有其他非变长类型参数则可变长参数列表必须放在最后面。、
Arrays类
Arrays.sort()、Arrays.parallelSort()
public static void main(String[] args) { int[] arr = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; reverseArr(arr); System.out.println(Arrays.toString(arr)); // ==== 二分查找 ==== System.out.println(Arrays.binarySearch(arr, 5)); // 4 // 将返回 -(insertion point + 1), insertion point如何计算是0在数组中应该顺序插入的下标 System.out.println(Arrays.binarySearch(arr, 0)); // -(0 + 1) => -1 // ==== 数组比较 ==== int[] arr01 = {1, 2, 3, 4, 5}; int[] arr02 = {1, 2, 3, 4, 5}; int[] arr03 = arr01; System.out.println(arr01 == arr02); // false 因为这里比较的是栈值既所指向堆内存地址空间是否相同 System.out.println(arr01 == arr03); // true 因为arr01和arr03都是指向同一块堆内存空间 System.out.println(Arrays.equals(arr01, arr02)); // true arr01和arr02所指向的数组中内容相等 System.out.println(Arrays.equals(arr01, arr03)); // true arr01和arr03所指向的数组中内容相等 // ==== 数组填充 ==== int[] list01 = {2, 4, 7, 10}; int[] list02 = {2, 4, 7, 7, 7, 10}; Arrays.fill(list01, 5); // Fill 5 to the whole array Arrays.fill(list02, 2, 5, 8); // Fill 8 to a partial array(startIndex:1,endIndex:5-1) System.out.println(Arrays.toString(list01)); // list01: [5, 5, 5, 5] System.out.println(Arrays.toString(list02)); // list02: [2, 4, 8, 8, 8, 10] } // 对int型数组逆转 public static void reverseArr(int[] sourceArr){ int low = 0; int high = sourceArr.length; int mid = (low + high) / 2; for(int i = 0; i < mid; i++){ sourceArr[i] = sourceArr[i] + sourceArr[high - 1 - i]; sourceArr[high - 1 - i] = sourceArr[i] - sourceArr[high - 1 - i]; sourceArr[i] = sourceArr[i] - sourceArr[high - 1 - i]; } }
java.util.Array.sort方法对【基本数据类型】排序,在此排序过程中不会创建新的数组
java.util.Array.binarySearch(array, key)对数组进行二分查找的前提是先将数组按照【升序】进行排列
To sum up
- 声明数组变量
eg: int[] arr;
是不会分配任何空间,数组变量不是基本类型变量包含对数组的引用。 - 创建数组之后,其大小无法改变,可以使用
arrayRefVar.length
得到数组的大小。 - 数组默认值 => (基本类型 - 0)、(字符类型 - '\u0000')、(布尔类型 - false)
- 数组创建的两种方法: 第一种.先造好房子添加默认值后再插入值 第二种.在造房子的同时插入值
int[] arr = new int[3]; // 此时数组默认值为0 eg: arr[0] = arr[1] = arr[2] = 0 arr[0] = 101; arr[1] = 102; arr[2] = 103; int[] arr = {321, 324, 323};
课后习题
- 编写程序,读取10个整数,按照和读入顺序的相反顺序将其输出
public class DemoTest01 { public static void main(String[] args) throws IOException { BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String[] strArr = bf.readLine().split(" "); reverseArr(strArr); System.out.println(Arrays.toString(strArr)); } /* 1 2 3 4 5 6 7 8 9 10 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] * */ private static void reverseArr(String[] arr){ int low = 0; int high = arr.length; int mid = (low + high) / 2; for(int i = 0; i < mid; i++){ String temp = arr[i]; arr[i] = arr[arr.length - 1 - i]; arr[arr.length - 1 - i] = temp; } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具