初识Java:数组
📚 目录
1.数组的概念
2.数组的创建和基本用法
2.1.数组的创建
2.2.数组的初始化
2.3.静态初始化
2.4.动态初始化3.数组的基本使用方法
3.1.引用类型:数组
3.2.引用类型和基本类型区别4.数组在函数中的使用
4.1.不作为函数的参数
4.2.作为函数参数
4.3.作为函数返回值5.二维数组
5.1普通的二维数组的创建和初始化
5.2.不规则的二维数组
前言:
如果你刚接触编程,大概率会在学习数组后不久遇到一个 “进阶版” 概念 —— 二维数组。它不像一维数组那样只是简单的 “一串数据”,而是像一张表格、一个棋盘,甚至是一张像素图,把数据以 “行 + 列” 的形式规整排列,也是连接基础编程与复杂数据处理的第一道关键桥梁。
希望这篇文章能帮你摆脱对二维数组的 “畏难感”,让你不仅 “会用”,更能 “理解为什么这么用”—— 毕竟编程的核心,从来都是把复杂问题拆解成可操作的简单逻辑。
1. 数组的概念
什么是数组?
数组:是相同类型元素的集合。(和C语言中的概念是一样的)
1:在内存空间上是连续的。
2:数组的下标从0开始一直到数组长度-1的位置。
3:引用类型:数组本身存放在堆内存中,数组名(变量)存放在栈内存,指向堆中的数组地址。
数组越界异常:如果访问的索引超出 0 ~ 长度-1 的范围,会抛出 :
ArrayIndexOutOfBoundsException
Java中数组没有初始化的时候是有默认值的,例如:
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[10];for(inti=0;i<array.length-1;i++){System.out.print(array[i]+" ");}}}
多维数组:比如二维数组 int[][] matrix = {{1,2}, {3,4}},可以理解为 “数组的数组”,常用于表示表格、矩阵等
2. 数组的创建和基本用法
数组的创建:
创建方式:
type[]数组名字=newtype[大小];publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[10];}}创建方式2:
type 数组名字[]={数组内容};//不推荐,这是C语言的写法,不建议在Java中使用数组的初始化
数组的初始化又能分为动态初始化的静态初始化。
静态初始化:
静态初始化就是我们在创建数组的时候就已经初始化完成了。例如:
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};}}也能这么写:分为两步
publicclassTest{publicstaticvoidmain(String[]args){int[]array;array=newint[]{1,2,3};}}动态初始化:
动态初始化:就是我们在创建数组的时候指定数组的长度,例如:
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[3];}}注意:
静态初始化的时候虽然没有指定长度,但是编译器会自己确定长度。
数据类型必须和[ ]前一致。
数组创建时没有初始化时各个类型的初始值:
3. 数组的基本使用方法
通过下标引用来访问各个数组中的元素;通过循环来遍历各个数组元素:例如:
方法1:
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};for(inti=0;i<array.length;i++){System.out.print(array[i]);}}}Java中给我们提供了快速算数组长度的方法: array.length
方法2:
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};for(intx:array){System.out.print(x);}}}for-each 是for 循环的另外⼀种使用方式.能够更方便的完成对数组的遍历.可以避免循环条件和更新语
句写错。
方法三:借助工具来进行遍历:Arrays.toString()
publicclassTest{publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};System.out.println(Arrays.toString(array));}}引用类型:数组
Java虚拟机中给内存的使用划分了空间:
引用数据类型创建的变量,⼀般称为对象的引⽤,其空间中存储的是对象所在空间的地址。
引用类型和基本类型的区别:
publicclassTest{publicstaticvoidswap(inta,intb){inttemp=a;a=b;b=temp;}publicstaticvoidswap(int[]array){inttemp=array[0];array[0]=array[1];array[1]=temp;}publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};inta=1;intb=2;System.out.println("===基本类型===");swap(a,b);System.out.print(a+" "+b);System.out.println();System.out.println("===引用类型===");swap(array);System.out.print(array[0]+" "+array[1]);}}
从上图可以看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。
数组在函数中的使用:
不作为函数的参数:
publicclassTest{publicstaticvoidfunc(intx){x=10;System.out.println("x = "+x);}publicstaticvoidmain(String[]args){intn=0;func(n);System.out.println(n);}作为函数的参数:
publicclassTest{publicstaticvoidswap(int[]array){inttemp=array[0];array[0]=array[1];array[1]=temp;}publicstaticvoidmain(String[]args){int[]array=newint[]{1,2,3};swap(array);System.out.print(array[0]+" "+array[1]);}}总结:所谓的"引用"本质上只是存了一个地址.Java将数组设定成引用类型,这样的话后续进行数组参数传参,其实只是将数组的地址传⼊到函数形参中.这样可以避免对整个数组的拷贝。
作为函数的返回值
publicclassTest{publicstaticint[]fib(intn){if(n<=0){returnnull;}int[]array=newint[n];array[0]=array[1]=1;for(inti=2;i<n;++i){array[i]=array[i-1]+array[i-2];}returnarray;}publicstaticvoidmain(String[]args){int[]array=fib(10);for(inti=0;i<array.length;i++){System.out.print(array[i]+" ");}}}数组array 指向了函数fib开辟存储数组的内存堆。
二维数组:
普通的二维数组的创建和初始化
数据类型[][]数组名称=new数据类型[⾏数][列数]{初始化数据};//二维数组的创建和初始化int[][]arr={{1,2,3,4},{5,6,7,8},{9,10,11,12}};也可以这么写;
publicclassTest{publicstaticvoidmain(String[]args){int[][]array=newint[2][3];}}或者这样:
publicclassTest{publicstaticvoidmain(String[]args){int[][]array=newint[][]{{1,2,3},{1,2,3}};}}注意:
二维数组是特殊的一维数组
array.length代表⼆维数组的行数
array[row].length 代表⼆维数组的列数
不规则的二维数组:
int[][]array=newint[2][];array[0]=newint[3];array[1]=newint[5];就是当没有给二维数组的列进行定大小的时候,向上面这样写就会变成不规则的二维数组。
总结:
不规则二维数组(锯齿数组)的核心优势是适配天然非规整的数据集,避免规则数组的内存浪费,更贴合实际业务场景;
典型应用包括存储长短不一的结构化数据、实现稀疏矩阵、处理树形 / 层级数据、游戏地图逻辑等;
Java 中使用时需注意:外层数组先定义长度,内层数组动态初始化,遍历时通过arr[i].length获取每行实际长度,防止越界。
