一维数组
数组初始化的三种方式
数组的默认初始化
数组是引用类型(除了八大基本数据类型,都是引用类型),他的元素相当于类的实例变量。其中每个元素也按照实例变量的方式倍隐式初始化。
静态初始化
int[] array={1,2,3};
Man[] mans={new Man(1,1),new Man(2,2)};//这是引用类型
动态初始化
int[] array=new int[10];
array[0]=1;
package MethodDemo;
public class Demo08 {
public static void main(String[] args) {
// int[] array = new int[7];//两种方法效果相同,但是这个更简洁
int[] array;//声明,操作之后会压栈
array = new int[7];//创建,操作之后会在堆里面开辟一定的空间
for (int i = 0; i < array.length; i++) {
array[i] = i;
System.out.println("array[" + i + "]" + "=" + array[i]);
}
}
}
创建数组操作内存的过程:
第一步声明一个数组时,JDK会分配一个空间进行压栈,但是此时并没有分配空间
第二步对数组进行初始化,JDK会在堆内分配一定数量的内存空间
第三步赋值操作,JDK会按照顺序进行赋值,如果不赋值,数组内保存的就是默认值(int类型的默认值是0)
当然,书写代码并不一定非要是上述的步骤,可以直接使用一行代码完成,但是内存操作还是相同的。
关于java内存的补充
数组边界
数组下标的合法区间是[0,length-1],如果越界,就会报错:ArraylndexOutOfBoundsException:数组下标越界异常!
数组也是对象。数组元素相当于对象的成员变量。
数组的使用
普通 的for循环
for-each循环
数组作为方法的形参
数组作为返回值
练习
package MethodDemo;
public class Demo08 {
public static void main(String[] args) {
int[] array = new int[5];
//给一维数组赋值
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
PrintArray(array);
System.out.println("--------------");
int[] reverseArray = ReverseArray(array);
PrintArray(reverseArray);
}
//把原来数组里面的元素倒序输出
public static int[] ReverseArray(int[] ArrayTemp) {
// int[] Re_array = new int[ArrayTemp.length];
// for (int i = 0, j = Re_array.length-1; i < Re_array.length; i++, j--) {
// Re_array[j] = ArrayTemp[i];
// }
// return Re_array;
int temp;//使用一个中间变量依然可以实现倒序输出
for (int i = 0; i < ArrayTemp.length/2; i++) {
temp = ArrayTemp[i];
ArrayTemp[i] = ArrayTemp[ArrayTemp.length - i-1];
ArrayTemp[ArrayTemp.length - i - 1] = temp;
}
return ArrayTemp;
}
//打印数组里面的元素的方法
public static void PrintArray(int[] ArrayTemp) {
// for (int i = 0; i < ArrayTemp.length; i++) {
// System.out.println(ArrayTemp[i]);
// }
//增强型for循环省去了数组下标
for (int i : ArrayTemp) {
System.out.println(i);
}
}
}
数组补充
2020/10/17/22:22
package Arrays;
public class testArray {
public static void main(String[] args) {
int[] array = new int[2];
for (int i = 0; i < array.length; i++) {
array[i] = i;
System.out.print(array[i]+" ");
}
System.out.println();
Car[] cars = new Car[2];
// cars[0]= new Car("奔驰");
// cars[0] = new Car(10);
// cars[1] = new Car("比亚迪");
// cars[1] = new Car(12);
cars[0] = new Car("奔驰", 10);
cars[1] = new Car("比亚迪", 12);
for (int i = 0; i < cars.length; i++) {
System.out.print(cars[i].name+" ");
System.out.println(cars[i].length);
}
System.out.println(cars.length);
}
}
package Arrays;
public class Car {
String name;
int length;
public Car(String name) {
this.name = name;
}
public Car(int length) {
this.length = length;
}
public Car(String name, int length) {
this.name = name;
this.length = length;
}
}
运行结果:
这里是自定义的数组类型,使用起来的感觉跟C语言里面的结构体比较像。
我们看自定义类型的数组:Car类里面有两个属性,使用Car类new一个引用类型的数组,那么这个数组的每个元素都包含Car类的所有属性(至于包不包含Car类里面的方法还不清楚,不过我判断是包含的,只不过是包含方法的引用地址),也就是说,数组car[i]里面存的是Car类里面每个属性的地址,其内存图如下:
需要注意的是:如果使用下面的方法对引用类型数组进行初始化,输出结果就是:
cars[0]= new Car("奔驰");
cars[0] = new Car(10);
cars[1] = new Car("比亚迪");
cars[1] = new Car(12);
运行结果:
为什么会这样,明明对name属性赋值了,内存中却是null?
经调试发现:我初始化引用数组元素的属性时,使用的是有参构造方法(一个参数),运行完“奔驰”的赋值后,cars[0].name确实被初始化成功,此时cars[0].length也被初始化了,只不过被初始化成默认值0(经测试:正确),也就是说我调用一个参数的构造方法时,JDK对另一个参数也进行了初始化(初始化成默认值),同理,执行cars[0] = new Car(10);这一句时,又调用一次一个参数的构造方法把cars[0].length初始化为10,此时cars[0].name也被初始化成默认值null。