一、一维数组
java中数组内存在堆上,栈上存这块内存的地址,而在C语言中数组的内存在栈上,注意:java中的数组是引用类型
1、数组的定义
java中定义数组时无需指定大小,会自动匹配出数组大小,例如:
int[] array1 = {1,2,3,4,5};
int[] array2 = new int[]{1,2,3,4,5,6,7};
int[] array3 = new int[4];//元素值为0,不是随机值
也就是说array1、array2、array3都在栈上,存放的是对应内存的地址(引用),而new出的内存都在堆上,array1、array2、array3都是引用,引用的就是new的对象。
如图:
如果数组的元素是引用类型,就是每一个元素都要new一个对象,元素保存在栈上,对象保存在堆上。
2、数组的属性和方法
(1)length为数组的属性,求数组的长度,例如
int len = array.length;
(2)遍历数组
和C语言一样,我们可以采用for循环或者while循环遍历数组,在java中还有几种方法,例如使用foreach方法,例如:
for(int val: array){
System.out.println(val);
}
可以使用Arrays这个工具类的toString方法,表示将数组以字符串的形式进行输出,例如:
int[] array = {1,2,3,4,5};
String str = Arrays.toStrng(array);
System.out.println(str);
或者直接
System.out.println(Arrays.toString(array));
数组的空引用是null,代表数组引用的是一个空对象,不是0地址,例如:
int[] array = null;
3、数组的四种拷贝
(1)使用for循环进行拷贝
(2)使用Arrays.copeOf()方法进行拷贝,例如:
int[] array1 = {1,2,3,4,5};
int[] ret = Arrays.copyOf(array1,array1.length);
for (int val: ret) {
System.out.print(val + " ");
}
打印出的结果就是1 2 3 4 5;
(3)System.arraycopy()方法进行拷贝,使用如下:
int[] array1 = {1,2,3,4,5};
int[] ret = new int[array1.length];
System.arraycopy(array1,0,ret,0,array1.length);
for(int i = 0;i<ret.length;++i){
System.out.println(ret[i]);
}
表示将array1的所有元素从0下标开始拷贝到ret从0下标开始中
(4)clone()方法进行克隆,例如:
int[] array = {1,2,3,4,5,6};
int[] ret = array.clone();
for (int val: ret) {
System.out.println(val);
}
也就是产生了一个副本,这个方法是Object类的克隆方法,Object是所有类的父类。
注意:这四种拷贝方式都是浅拷贝
深拷贝和浅拷贝:
例如将array1的元素拷贝到array2,如果通过array2修改array2自己的元素,不会影响到array1,这种拷贝叫做深拷贝,例如数组中存的是简单类型的元素,进行拷贝就是深拷贝;
例如若数组array1中存放的引用类型,将array1的元素拷贝到array2中,,如果通过array2修改array2自己的元素,此时会将array1的元素也改为array2修改的内容,这种就叫做浅拷贝,因为引用本质上是地址,数组的元素是引用类型,拷贝一份其实就是拷贝地址,相同的地址如果一个发生改变,另一个也会发生改变,如果要实现深拷贝,可以将每个引用所指向的对象也拷贝一份。
4、数组的常用方法
(1)拷贝指定区间的内容,Arrays.copyOfRange(),例如:
int[] array = {1,2,3,4,5,6};
int[] ret = Arrays.copyOfRange(array,2,5);
for (int val: ret) {
System.out.println(val);
}
打印出的结果为3 4 5,表示打印从2到5的内容
(2)判断两个数组内容是否相同:Arrays.equals(array1,array2),例如:
int[] array1 = {1,2,3,4,5,6};
int[] array2 = {1,2,3,4,5,6};
boolean flag = Arrays.equals(array1,array2);
if(flag == true){
System.out.println("两个数组内容相同");
}
else{
System.out.println("不同");
}
结果为两个数组内容相同。
(3)给数组进行填充,例如:
int[] array = new int[10];
Arrays.fill(array,8);//表示给数组所有的元素都填充为8
for (int e: array) {
System.out.print(e);
System.out.print(" ");
}
System.out.println();
//局部填充
int[] ret = new int[10];
Arrays.fill(ret,2,5,8);//表示对2下标到5下标的元素填充8
for (int val: ret) {
System.out.print(val);
System.out.print(" ");
}
打印出的结果为:
二、二维数组
二维数组本质上也是一个一维数组,不同的是每个元素是一个一维数组。
1、二维数组的定义
例如:
int[][] array = {{1,2,3},{4,5,6}};
int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
int[][] array3 = new int[2][3];
如图为java中二维数组的内存结构:
2、打印二维数组除了使用嵌套双层循环以外,可以使用Arrays.deepToString()方法转换为字符串进行打印,例如:
int[][] array = {{1,2,3},{4,5,6}};
System.out.println(Arrays.deepToString(array));
打印结果为:
当然也可以使用foreach进行打印,例如:
int[][] array = {{1,2,3},{4,5,6}};
for (int[] t:array) {
for (int val: t) {
System.out.print(val+" ");
}
System.out.println();
}
3、规则二维数组和不规则二维数组
规则二维数组就是指定行和列的数组,不规则二维数组就是指定行不指定列,例如:
int[][] array = new int[2][3];//规则数组
int[][] array1 = new int[2][];//不规则数组
System.out.println(Arrays.deepToString(array1));
但是注意在C语言中可以指定列,行会自动推导出来,而在java中必须指定行,但是列不会自动推导出来,上述的结果就是空指针
因此不规则数组要进行初始化,例如:
int[][] array1 = new int[2][];//不规则数组
array1[0] = new int[]{1,2,3};
array1[1] = new int[]{4,5};
System.out.println(Arrays.deepToString(array1));
//也可以
array1[0] = new int[3];
array1[1] = new int[2];
System.out.println(Arrays.deepToString(array1));
结果为: