恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
【java】数组的定义和使用
首页
资讯中心
/
【java】数组的定义和使用
【java】数组的定义和使用
发布时间:2026/9/12 19:40:23
数组的基本概念数组创建T[] 数组名 new T[N];T数组中存放元素的数据类型T [] 代表数组本身的类型N数组的长度数组能存放多少个元素int[] arr1new int[10]; double[] array2new double[10]; String[] array3new String[20];数组两种初始化方式动态初始化创建数组时只指定数组长度不写元素值元素自动赋默认值只规定数组大小里面元素是对应类型的默认值//静态初始化 int[] array1new int[10];静态初始化创建数组时直接写出数组里面的元素编译器自动根据大括号里元素个数算出数组长度//动态初始化 int[] array2new int[]{1,2,3,4,5,6,7,8,9}; double[] array3new double[]{1.0,2.0,3.0,4.0}; String[] array4new String[]{tom,Lily,java};数组元素默认值当数组只开辟空间没有手动赋值时元素自带默认值引用类型String、类对象等默认值nullString[] words new String[3]; // 三个元素默认都是null重点注意事项静态初始化不用手动写长度编译器自动数{}里元素个数。{}里的数据类型必须和数组定义的类型一致。简写格式{...}不能拆分成两行定义int[] array5; array5new int[]{1,3,5,3,6,7}; //这样是可行的 int[] array6; array6{1,2,34,54,65};//编译报错简写只能在定义数组那一行初始化 int[] array7{1,2,3,4,5,6}; //在定数组这一行初始化是可行的数组的基本使用数组中元素访问数组在内存是连续空间下标从 0 开始递增通过数组[下标]访问元素int[] array1new int[]{10,20,30,40,50}; System.out.println(array1[0]); System.out.println(array1[2]); System.out.println(array1[3]); // 修噶下标为0 的元素、 array1[0]1; System.out.println(array1[0]);注意事项连续内存 → 支持随机访问直接用下标快速读取任意位置元素。下标范围[0, 数组长度)不能越界。数组有N个元素下标最大是N-1下标越界抛出异常遍历数组遍历把数组里所有元素全部访问一遍方式 1for 循环能拿到数组下标利用数组名.length 获取数组长度int[] array1new int[]{1,2,3,4,5,6}; for(int i0;iarray1.length;i) { System.out.printf(%d ,array1[i]); } System.out.println();方式 2for-each 增强 for 循环只读取元素拿不到下标语法for(元素类型 变量 : 数组名)特点不用写循环条件简化遍历无法获取当前元素下标//for-each 增强for循环 int[] array2new int[]{1,3,4,5,6}; for(int x:array2) { System.out.printf(%d ,x); } System.out.println();数组是引用类型基本类型变量与引用类型变量的区别基本类型变量栈里面直接存值本身引用类型变量栈里面存对象在堆中的地址对象本体放在堆里基本数据类型创建的变量称为基本变量该变量空间中直接存放的是其所对应的值引用数据类型创建的变量⼀般称为对象的引用其空间中存储的是对象所在空间的地址引用变量并不直接存储对象本身可以简单理解成存储的是对象在堆中空间的起始地址通过该地址引用变量便可以去操作对象Java 的引用类似 C 语言指针但 Java 不能手动对地址做加减运算安全性更高public static void func1() { int[] array1new int[3]; array1[0]10; array1[1]20; array1[2]30; int[] array2new int[]{1,2,3,4,5}; array2[0]100; array2[1]200; // 变量里存的不是变量本身而是在堆内存的地址 array1array2; //两个变量共用同一块内存地址 array1[2]300; array1[3]400; array1[4]500; for(int i0;iarray2.length;i) { System.out.println(array2[i]); } }关键总结Java 数组属于引用类型a变量里存的不是数组本身而是数组在堆内存的地址barray1 array2 只是拷贝地址两个变量共用同一个数组对象c无论用哪个引用修改数组内部元素都会互相影响NULL什么是 nullanull 在 Java 中表示空引用是一个不指向任何对象的引用bJava 里引用类型数组、类、String 等的变量可以赋值为 null代表这个引用 变量没有指向堆里的任何对象c基本数据类型int / double / boolean不能赋值为 null只有引用类型可以和 C 语言 NULL 的区别相似点都代表无效的内存位置不能读写重要区别Java 的 null不等价于内存 0 号地址只是 Java 层面的 “空标记”和 C 语言空指针底层含义不一样空指针什么时候会出现只要用一个值为null的引用去调用属性 / 方法 / 访问数组元素就会触发 NPE总结int[] arr1null; int[] arr2new int[]{1,2,3,4,5,6,7}; System.out.println(arr1[0]); // System.out.println(arr2[0]);aarr1只是一个空引用不存在数组arr1[0] 空指针barr2数组对象存在可以访问元素arr2[0] 是 1数组的应用场景保存数据知识点a数组用来批量保存多个同类型数据b数组下标从 0 开始最大下标 数组长度 -1c数组名.length获取数组元素个数dfor 循环适合知道循环次数的遍历场景int[] array{1,2,3}; for(int i0;iarray.length;i) { System.out.println(array[i] ); }参数传递值传递Java 中只有值传递没有引用传递基本类型和引用类型本质都是拷贝一份 “值” 传给方法基本数据类型作为参数public static void main(String[] args) { int num 0; func(num); System.out.println(num num); } public static void func(int x) { x 10; System.out.println(x x); }斐波那契数列//方法返回int[]数组存放婓波那些前n项 public static int[]fib(int n) { if(n0) { return null; } int[] arraynew int[n]; array[0]array[1]1; //当前项等于前两项之和 for(int i2;in;i) { array[i]array[i-1]array[i-2]; } return array; }Arrays 工具类 和 数组知识点Java 数组常用操作包含Arrays工具类、数组拷贝、查找、排序、逆序数组转字符串 Arrays.toString()作用快速把数组转为字符串格式打印不用自己循环拼接int[] arrnew int[]{1,2,3,4,5,6,7}; String newArr Arrays.toString(arr); System.out.println(newArr);注意直接打印数组对象名输出的是地址哈希值不是数组内容数组拷贝直接赋值浅引用不是拷贝int[] arrnew int[]{1,2,3,4,5}; int[] newArrarr; //newArr 和 arr 指向的是同一块数组 newArr[0]100; System.out.println(Arrays.toString(arr)); // newArr 的修改 会导致 arr 也被修改Arrays.copyOf / Arrays.copyOfRange真正拷贝生成新数组//Arrays.copyOf/Arrays.copyOfRange 是拷贝 int[] arrnew int[]{1,2,3,4,5,6,7}; //copyOf(原数组新数组长度) int[] newArrArrays.copyOf(arr,arr.length); arr[0]10; System.out.println(arr: Arrays.toString(arr)); System.out.println(newArr: Arrays.toString(newArr)); //不受arr 的影响 //copyOfRange (原数组起始下标结束下标) //左闭右开 int[] newArr2Arrays.copyOfRange(arr,1,5); System.out.println(newArr2: Arrays.toString(newArr2));区分基本类型数组拷贝没问题引用类型数组拷贝是浅拷贝自己手写数组拷贝public static int[] copyOf(int[] arr) { int[] retnew int[arr.length]; for(int i0;iarr.length;i) { ret[i]arr[i]; } return ret; }功能手写版数组拷贝深拷贝对于 int 基本类型数组复制完成后修改原数组arr不会影响新数组ret修改ret也不会影响arr顺序查找线性查找从头到尾逐个比对元素找到返回下标找不到返回 -1//顺序查找找到返回下标找不到返回-1 public static int find(int[] arr,int data) { for(int i0;iarr.length;i) { if(arr[i]data) { return i; } } return -1; }缺点数据量大的时候效率低不需要数组有序二分查找折半查找思路取中间元素比较目标值缩小查找区间//二分查找 public static int binarySearch(int[] arr,int toFind) { int left0; int rightarr.length-1; while(leftright) { int mid(leftright1)/2; if(toFindarr[mid]) { rightmid-1; } else if (toFindarr[mid]) { leftmid1; } else { return mid;// 找到 } } return -1; //没找到返回 -1 }优点数据越多效率优势越大Java 自带Arrays.binarySearch()方法int ret2Arrays.binarySearch(arr,6); System.out.println(ret2);数组排序冒泡排序升序思路相邻两个元素比较前大后小就交换每一轮把最大元素“冒泡” 到末尾降序思路相邻两个元素比较前小后大就交换每一轮把最小元素“冒泡” 到末尾public static void bubbleSort(int[] arr) { //外层控制轮数 //内层比较每轮末尾 i 个已经排好的不用比较 for(int i0;iarr.length;i) { for(int j0;jarr.length-i-1;j) { //如果前面的比后面的数据大,就交换 if(arr[j]arr[j1]) //要改成降序的话把大于改成小于就行 { int temparr[j]; arr[j]arr[j1]; arr[j1]temp; } } } }Java 内置Arrays.sort(arr)底层是优化后的排序性能远高于手写冒泡数组逆序思路双指针left 指向头部right 指向尾部交换两个元素leftright--直到left right// 数组逆序 双指针 先交换元素在变化指针 public static void reverse(int[] arr) { int left0; int rightarr.length-1; while(leftright) { int tmparr[left]; arr[left]arr[right]; arr[right]tmp; left; right--; } }二维数组普通二维数组二维数组本质是一维数组数组里每一个元素又是一个一维数组语法格式数据类型[][] 数组名称 new 数据类型 [行数][列数] {初始化数据};特点行不能省略列可以省略// 二维数组 public static void main(String[] args) { int[][] a{ {1,2,3,4}, {5,6,7,8}, {9,10,11,12} }; //a.length 是行数 for(int row0;rowa.length;row) { //a[row].length 是列数 for(int col0;cola[row].length;col) { System.out.printf(%d\t,a[row][col]); } //换行 System.out.println(); } }a.length二维数组行数a[row].length第row行一维数组的长度当前行的列数不规则二维数组定义时只确定行数每一行的列数不固定各行长度不一样int[][] array new int[2][]; // 定义2行列暂时不指定 array[0] new int[3]; // 第0行3个元素3列 array[1] new int[5]; // 第1行5个元素5列第 0 行3 列第 1 行5 列内存理解外层数组保存两个一维数组的地址两个一维数组长度不同