例如当我们要存学生的成绩并输出时,倘若有5个学生,那么我们可以定义五个变量来存储。
int score1 = 90;
int score2 = 85;
int score3 = 99;
int score4 = 88;
int score5 = 80;
System.out.println(score1);
System.out.println(score2);
System.out.println(score3);
System.out.println(score4);
System.out.println(score5);可是当有100个或者更多个学生时,这样就显得太麻烦了 ,因此我们需要引入数组来更方便的存储多个相同类型的数据。
所谓数组可以看成是相同类型元素的一个集合,他在内存中是一段连续的空间。

数组的创建格式为:T[ ] 数组名 = new T[N]
int[] array1 = new int[5];
String[] array2 = new String[3];创建数组时直接给出N的值
int[] array = new int[5];此时数组中所有元素的值都默认为0,并且我们可以通过数组的下标去访问里面的元素。
静态初始化不直接指定元素的个数,而是将要存放的内容直接给定。
int[] arr = new int[]{1,2,3,4,5};
String[] arr1 = new String[]{"wangwu","lisi"};并且,静态初始化可以简写,直接省去后面的new T[ ]
int[] arr = {1,2,3,4,5}; java中数组也可以使用c语言的方式进行创建与初始化
int arr[] = {1,2,3,4,5};1.使用循环进行遍历
int[] array = new int[]{1,2,3,4,5};
for (int i = 0; i < 5; i++) {
System.out.println(array[i]);
}当前数组元素个数为5,因此i<5,可是当数组长度很长时,我们获取数组长度怎么办呢,难道一个一个去数吗? 在java的开发工具中,通过数组名.length可以直接获取到数组的长度。
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}现在不管数组长度多大,我们都可以利用.length来直接获取了。 2.使用for-each循环遍历
int[] array1 = {1, 2, 3, 4, 5};
for (int x : array) {
System.out.println(x);
}3.借助工具Arrays的toString方法遍历
String str = Arrays.toString(array);
System.out.println(str);
所有new出来的都是对象,都存放在堆区上。 数组是一个引用变量,他存放的是对象的地址,其引用指向了堆上的对象。例如:
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
int a = 10;
int b = 20;
}这个代码对应的内存如下

变量a,b所存的都是其对应的值,而数组是引用变量,它所存的是new出来的对象在堆上的地址,因此如果直接打印array,所得到的是地址,只有通过下标访问才能得到其元素的具体值。
public static void func() {
int[] array1 = new int[3];
array1[0] = 10;
array1[1] = 20;
array1[2] = 30;
int[] array2 = new int[]{1,2,3,4,5};
array2[0] = 100;
array2[1] = 200;
array1 = array2;
array1[2] = 300;
array1[3] = 400;
array1[4] = 500;
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i]);
}
}
public static void main(String[] args) {
func();
}在array1 = array2 之前,内存为:

此时,array1和array2两个引用分别指向各自对象在堆上的地址,且各元素值如上图,当array1 = array2 语句执行过后,内存图改变:

array1 引用指向地址改变为 array2 引用指向的地址,此时 array1 与 array2 指向的是同一个地址,因此,当下面三条赋值语句执行时,array1 里面元素与 array2 里面元素的值都发生了改变(因为他们指向地址一样,存储的元素地址,数值都是一样的),因此最后输出为100,200,300,400,500。
这两个例子希望能更好的理解数组引用类型变量。
这个相比不用多说,能够更方便的存储同类型的变量数据。
public class Array {
public static void func(int ret){
ret = 50;
System.out.println("ret = " + ret);
}
public static void main(String[] args) {
int a = 10;
func(a);
System.out.println("a = " + a);
}
}
//输出结果
//ret = 50
//a = 10首先,基本数据作为函数的基本类型,因为基本变量存的是值,传参时为值传递,改变形参的值时,实参的值并不发生改变。那么数组引用类型变量的参数传递又是什么样呢?
public class Array {
public static void func(int[] array){
array[2] = 100;
System.out.println("array[2] = " + array[2]);
}
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
System.out.println("array[2] = " + array[2]);
func(array);
System.out.println("array[2] = " + array[2]);
}
}
//输出结果
//array[2] = 3
//array[2] = 100
//array[2] = 100发现初始时array[2]的值为3,当作为参数传递后,形参发生改变时,实参也发生了改变,3变为了100。 这是由于数组引用变量存的是对象在堆上的地址,将地址作为值进行了传递,而形参拿到这个地址值后,引用指向了实参指向的地址,因此形参改变也带动了实参的改变。
例如,我们想要将数组逆序输出。
public class Array {
public static int[] func(int[] array){
int psv = 0;
int end = array.length-1;
while (psv < end){
int tmp = array[end];
array[end] = array[psv];
array[psv] = tmp;
psv++;
end--;
}
return array;
}
public static void main(String[] args) {
int[] array = new int[]{1,2,3,4,5};
System.out.println(Arrays.toString(func(array)));
}
}二维数组和一维数组创建初始化基本一样。
//动态
int[][] array1 = new int[2][3];
//静态
int[][] array = new int[][]{{1, 2, 3}, {4, 5, 6}};
int[][] array3 = {{1, 2, 3}, {4, 5, 6}};
其实不然,二维数组就是两个一维数组,那么其内存分布也应是两个一维数组的分布方式

这样看就显而易见了,array实际上存的是一个一维数组的地址,而这个一维数组的元素存的又分别是各自指向的一维数组的地址。那么,当这样输出时:
System.out.println(array.length);,
System.out.println(array[0]);,
System.out.println(array[0].length);
应该分别是什么,第一个应该是2,第一个是一个一维数组的地址,第三个为3(深一维数组的长度)。这样就不难理解了。
1.for循环遍历 当搞清楚二维数组的内存分布后,遍历起来就方便了(依然可以理解为 x 表示行,y表示列)
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
System.out.print(array[x][y] + " ");
}
System.out.println();
}2.Arrays的toString遍历
我们已经知道array实际上存的是一维数组的地址,因此当我们用Arrays.toString(array);遍历打印时,得到的其实是两个地址。
因此我们需要借助deepToString来遍历,Arrays.deepToString(array)使用这个打印时,我们可以得到结果:
System.out.println(Arrays.deepToString(array));
public class Array {
public static void main(String[] args) {
int[][] array = new int[2][];
array[0] = new int[3];
array[1] = new int[5];
for (int x = 0; x < array.length; x++) {
for (int y = 0; y < array[x].length; y++) {
System.out.print(array[x][y] + " ");
}
System.out.println();
}
}
}不规则二维数组实际上和二维数组是一样的,上面就是一个第一行为3个元素,第二行为5个元素的不规则二维数组,遍历是一样的。

其内存分布基本一样。