数组是用来存放同一类具有相同数据类型的元素的集合。它的出现解决通过定义大量变量接收数据浪费空间的情况。
数据类型[] 数组名 ;
数据类型 数组名[];
举个例子,比如我需要定义一个double类型的数组,如下
double[] d ;
我要定义一个字符串类型的数组
String [] s;
数组定义了以后,接下来就是给定义的数组进行初始化赋值,java提供了两种初始化的方法,一种是静态初始化,一种是动态初始化,下面就总结了这两种初始化的具体过程。
数据类型 [] 数组名 = new 数据类型[数组长度];
或者 数据类型 数组名[] = new 数据类型[数组长度];
因为数组也是引用对象,所以需要通过关键字new来创建数组对象。
比如你要定义一个长度为10的整形数组:int [] arr = new int[10];
比如你要定义一个长度为3的布尔类型的数组:boolean[3] b = new boolean[3];
静态初始化不用给出数组长度,长度是由系统给出的。
比如我要定义一个字符串数组,里面放三句话,爱生活,爱自己,爱java
String[] s = {"爱生活","爱自己","爱java"};
可以看出来,他是通过大括号直接为数组赋值,里面用逗号分隔,系统会为他自动分派三个内存空间
数组是定义出来了,但是它究竟在内存中如何存放呢?
栈内存:存放局部变量的内存空间,所谓局部变量就是定义在方法中或者方法声明上的变量。
堆内存:凡是关键字new 的都是存放在这里的,所以数组也是存在对内存的。
凡是通过关键字new出来的系统都会在堆内存中为其开辟一块空间,并为这个空间赋一个地址值,数组也不例外。数组算引用变量,所以他的传递不是值传递,而是地址值传递。
方法区:每一个java文件编译后生成的.class文件就会被加载进入方法区内。
还有本地方法区和寄存器,后面会持续补充。
下面有一个具体的图示,可以加深一下理解。
首先加载test类的字节码文件进入方法区,然后main方法进栈,执行前半部分定义变量int arr[];看见关键字new为其在堆内存中开辟3个单位大小的内存空间,为它附上地址值,最好将地址值给arr对象,实现通过地址值与内存一一对应。
数组定义出来了也为每一块空间附上对应的数值了,那么我们该如何取呢,请看下面这段程序。
public static void main(String[] args) { int[] arr={1,2,3,4,5,9,8}; System.out.println(arr[0]); System.out.println(arr[1]); System.out.println(arr[2]); System.out.println(arr[3]); System.out.println(arr[4]); System.out.println(arr[5]); System.out.println(arr[6]); }
这段程序确实也实现了所谓的显示出数组中的所有值,但是这样就显得程序特别的臃肿而且重复代码多的不能再多,所有是不可取的,那么我们会想到用循环来解决。
这里介绍一个数组特有的属性length属性。他可以取出数组的大小,请看下面这段程序,一样可以实现上面的功能
public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5, 9, 8}; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } }
一定要注意数组元素索引是从0开始的,如果超过数组长度,Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
索引看到控制台输出这段错误千万别慌,只需要检查一下数组索引是否错误就好了。
介绍完一维数组下来就是二维数组。
所谓二维数组,就是一个数组的元素全部为数组,比较抽象,看下下面的定义就知道了,只要学好一维数组,二维数组也不在话下。
数据类型[][] 变量名 = new 数据类型[m][n];
这里的m表示这个二维数组有多少个一维数组,而n表示每一个一维数组的元素个数;
举个例子,比如我要定义一个二维数组,这个二维数组里面需要定义三个一维数组,且每个数组的长度均为3,依旧是两种方式
动态初始化:int [][] arr = new int[3][3];
静态初始化:int[] [] arr ={{x,x,x},{x,x,x},{x,x,x}};
这个二维数组有三个元素分别为三个一维数组,arr[0],arr[1],arr[2];
每个一维数组有三个元素,他的值可以通过arr[n][m]来取,比如我要取第一个数组的第一个元素就是arr[0][0]。
数据类型 数组名[][] = new 数据类型[m][n]; 数据类型[] 数组名[] = new 数据类型[m][n]; 这两种类型也可以定义二维数组。
来看一下下面这段代码吧:
public static void main(String[] args) { int[][] arr =new int[2][3]; arr[0][0]=1; arr[0][1]=2; arr[1][0]=3; arr[1][1]=4; arr[1][2]=5; System.out.println(arr[0]); System.out.println(arr[0][1]); System.out.println(arr[1][2]); }
这段代码执行结果如下:
第一个一维数组的地址值
2
5
首先arr[0]是表示第一个数组,是引用类型所以肯定打印但是地址值,后面的值分别对应的是第一个数组的第二个值,第二个数组的第三个值。
一维数组的遍历是通过一个for循环,那么二维数组是一维数组嵌套,肯定是需要两个for循环嵌套,请看下面的代码
public static void main(String[] args) { //静态初始化 int[][] arr ={{1,2,3},{4,5,6},{7,8,9}}; for(int i=0;i
循环变量i控制的是二维数组中的第几个一维数组,j控制的是一维数组中的第一个元素的索引。
需求:公司年销售额求和某公司按照季度和月份统计的数据如下:单位(万元)
第一季度:27,66,44
第二季度:100,33,65
第三季度:35,45,69
第四季度:22,18,99
public static void main(String[] args) { int[][] arr = {{27, 66, 44}, {100, 33, 65}, {35, 45, 69}, {22, 18, 99}}; int sum=0; for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr[i].length; j++) { sum+=arr[i][j]; } } System.out.println("十二个月的销售额总计"+sum+"万元"); }
下面也通过一个图,来看一下二维数组在内存中的存储过程