目录
1.2 案例
前言
二维数组包含多个一位数组,将使用多个下标访问数组元素,同样下标是从0开始的。可以结合一维数组的基本知识来学习了解二维数组。在二维数组中的扩容与删除中,可以找到许多与一维数组的扩容与删除的相似之处。
可以通过下方链接温习一些简单的一维数组的知识,温故而知新。
提示:以下是本篇文章正文内容,下面案例可供参考
一、二维数组的声明及初始化
1.二维数组的声明
数据类型[][] 变量名;
声明一个数据类型为String的二维数组,数组名为str,代码示例如下:
String[][] str;
2.二维数组的初始化
对数组进行初始化之前是不能使用的。
2.1静态初始化
//静态初始化1:
String[][] str1 = new String[][]{{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//静态初始化2:
String[][] str2;
str2 = new String[][]{{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//静态初始化3:
String[][] str3 = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//静态初始化3的不同写法
String[][] str3 = {
{"元素0-0","元素0-1","元素0-2"},
{"元素1-0","元素1-1","元素1-2"}
};
静态初始化3没有使用new 操作符号,使用简写形式对二维数组进行初始化。
2.2动态初始化
如果知道了数组的长度,那么就可以使用动态初始化。
//动态初始化1:初始化一个包含了 两个数组长度为3的一维数组 的二维数组
String[][] names = new String[2][3];
//动态初始化2
String[][] names2;
names2 = new String[2][3];
动态初始化的二维数组同样被赋予了系统默认值(不同数据类型系统默认值不同)。
二、访问数组元素
1.设置元素
1.1 设置元素
代码如下(示例):
//动态初始化1
String[][] names = new String[2][3];
//获取长度
System.out.println("获取二维数组中包含的的一维数组个数:"+str1.length);//输出结果:2
System.out.println("获取二维数组中第一个一维数组的长度:"+str1[0].length);//输出结果:3
System.out.println("获取二维数组中第二个一维数组的长度: "+str1[1].length);//输出结果:3
//为动态初始化1的二维数组设置指定下标上的元素
names[0][0] = "元素0-0";
names[0][1] = "元素0-1";
names[0][2] = "元素0-2";
names[1][0] = "元素1-0";
names[1][1] = "元素1-1";
names[1][2] = "元素1-2";
//获取动态初始化1的二维数组的指定下标的元素
String n = names[1][1];
System.out.println("该下标元素为: " + n);
1.2 案例
初始化包含不同长度的一维数组的二维数组,可加深对创建二维数组的理解(代码示例如下)
/*
需求:创建一个二维数组,包含2个一维数组,其中第一个一维数组的长度为3,第二个一维数组的长度为4
*/
//创建一个包含两个一维数组的二维数组
String[][] names = new String[2][];
//设置在二维数组中下标为0的一维数组
names[0] = new String[]{"00","01","02"};
//设置在二维数组中下标为1的一维数组
names[1] = new String[]{"10","11","12","13"};
(实用性不高,但是有助于理解二维数组。)
2.遍历数组
2.1 嵌套for循环遍历
遍历思想:先遍历二维数组中的一维数组的个数,再遍历一维数组中的元素
代码如下(示例):
for(int i =0;i<names.length;i++){
for(int j =0;j<names[i].length;j++){
System.out.println(names[i][j]);
}
}
2.2 嵌套foreach遍历
for each 循环语句不能自动处理二维数组中的每一个元素,所以需要两个foreach嵌套。首先最外层的foreach语句先遍历二维数组中它包含的每一个一维数组,内层的foreach再遍历一维数组中的每一个元素。
//外层foreach
for(String[] ss : names){
//内层foreach
for(String element : ss){
System.out.println(element);
}
}
三、二维数组的拷贝
1.浅拷贝
原数组(str)和拷贝后的新数组(strCopy)的引用指向同一个数组的内存地址。
//原数组
String[][] str = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//新数组
String[][] strCopy;
//将原数组地址赋给新数组
strCopy = str;
需要注意的是新数组一开始并没有初始化,由于没有在初始化之前访问新数组中的元素,所以不会报错。也就是说在得到原数组的内存地址后,再访问新数组,访问的其实就是原数组。
2.深拷贝
原数组和拷贝后的数组指向两个不同的二维数组,是两个不同的内存地址。
2.1 for循环嵌套拷贝
//原数组
String[][] str = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//新数组(由于会操作新数组的下标,必须初始化)
String[][] strCopy = new String[2][3];
//利用双重for循环依次拷贝
for(int i=0;i < str.length; i++) {//遍历一维数组的个数
for(int j=0;j<str[i].length;j++) {//遍历一维数组
strCopy[i][j] = str[i][j];//依次拷贝
}
}
2.2 for循环+Arrays工具类中拷贝方法
//原数组
String[][] str = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//新数组(由于会操作新数组的下标,必须初始化)
String[][] strCopy = new String[2][3];
//方法3:Arrays.copyOf方法
for(int i = 0; i < str.length; i++) {
//调用Arrays工具类的copyOf方法
strCopy[i] = Arrays.copyOf(str[i], str[i].length);
}
需要额外注意的是:数组未初始化前不能使用。
四、二维数组的扩容
1.扩容二维数组中的一维数组的数量
将二维数组中一维数组的数量扩容为原先的1.5倍(代码示例如下)
//1.原数组
String[][] str = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//2.定义新数组中的一维数组的数量(原一维数组数量的1.5倍)
int oldCapacity = str.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
//3.循环比较二维数组中所有一维数组的长度,选出最长的长度,防止二维数组中一维数组长度不同造成的数组下标越界异常。
int n = oldCapacity-1;
int maxLenth = 0;
while(n>0) {
maxLenth = str[n].length > str[n-1].length? str[n].length : str[n-1].length;
n--;
}
//4.动态初始化新数组
String[][] newStr = new String[newCapacity][maxLenth];
//5.复制原数组中数据到新数组
for(int i = 0; i < oldCapacity; i++) {
for(int j = 0; j < str[i].length; j++) {
newStr[i][j] = str[i][j];
}
}
//6.将新数组引用赋给原数组
str = newStr;
//7.遍历原数组
for (String[] ss : str) {
for (String element : ss) {
System.out.println(element);
}
}
结果如下:
2. 扩容二维数组中的一维数组的容量
将二维数组中每一个一维数组的长度扩容为原先的2倍
//1.原数组
String[][] str = {{"元素0-0","元素0-1","元素0-2"},{"元素1-0","元素1-1","元素1-2"}};
//2.定义新数组中的一维数组的容量(原一维数组容量的2倍)
int oldCapacity = str[0].length;
int newCapacity = oldCapacity * 2;
//3.动态初始化新数组
String[][] newStr = new String[2][newCapacity];
//4.复制原数组中数据到新数组
for(int i = 0; i < str.length; i++) {
for(int j = 0; j < oldCapacity; j++) {
newStr[i][j] = str[i][j];
}
}
//5.将新数组引用赋给原数组
str = newStr;
//6.遍历原数组
for (String[] ss : str) {
for (String element : ss) {
System.out.println(element);
}
}
结果如下:
五、二维数组的删除
1.删除二维数组中某个一维数组
1.1 删除方式1
思路:将除了被删除的数组之外的数组复制到新数组中,再将新数组的地址引用赋给原数组
缺陷:减小了原有二维数组的所包含一位数组的数量,数组是存放数据的容器,最好不要轻易改小。
(代码示例如下)
/*
需求:删除{"xxx","xxx","xxx","xxx"}
*/
//1.原数组
String[][] str = {{"xxx","xxx","xxx","xxx"},{"大黄瓜","大南瓜","大西瓜","大冬瓜"},{"沙糖桔","红富士","丑橘","大香蕉"}};
//2.初始化一个除了删除元素之外的数组
String[][] deleteStr = new String[str.length-1][str[0].length];
//3.定义需要删除的一维数组的下标
int deleteRow = 0;
//4.除了删除的一维数组,将其他一维数组复制到新数组中
int index = 0;//记录新数组中一维数组的下标
for(int i = 0;i < str.length; i++) {
if(i != deleteRow) {
for(int j = 0; j<str[i].length; j++) {
deleteStr[index][j] = str[i][j];
}
index++;
}
}
//5.将新数组引用的数组地址赋值给原数组
str = deleteStr;
//6.遍历原数组
for (String[] ss : str) {
for (String element : ss) {
System.out.println(element);
}
}
结果如下:
1.2 删除方式2
思路:通过迁移(覆盖)删除特定的一维数组
好处:没有改变原有数组的大小。
/*
需求:删除{"xxx","xxx","xxx","xxx"}
*/
//1.原数组
String[][] str = {{"xxx","xxx","xxx","xxx"},{"大黄瓜","大南瓜","大西瓜","大冬瓜"},{"沙糖桔","红富士","丑橘","大香蕉"}};
//2.设置需要覆盖的一维数组的下一个下标
int index = 1;
//3.迁移覆盖指定下标之前的一维数组
for(int i = index; i<str.length; i++) {
for(int j = 0; j<str[i].length;j++) {
str[i-1][j] = str[i][j];
}
}
//4.将最后一个一维数组设置为null
for(int i = 0; i<str[str.length-1].length;i++) {
str[str.length-1][i] = null;
}
//5.遍历原数组
for (String[] ss : str) {
for (String element : ss) {
System.out.println(element);
}
}
结果如下:
2.删除二维数组中的一维数组中的某个元素
思路:通过遍历二维数组找到需要删除的元素,使用该元素之后的元素将其覆盖。
(代码示例如下)
/*
需求:删除丑橘
*/
//1.原数组
String[][] str = {{"xxx","xxx","xxx","xxx"},{"大黄瓜","大南瓜","大西瓜","大冬瓜"},{"沙糖桔","红富士","丑橘","大香蕉"}};
//2.循环遍历数组找到需要删除的元素
for (int i = 0; i < str.length; i++) {
for (int j = 0; j < str[i].length-1; j++) {
if(str[i][j].equals("丑橘")) {//判断如果为要删除的元素,就用它之后的元素覆盖此元素,并把该一维数组最后一个元素设置为null
str[i][j] = str[i][j+1];
str[i][str[i].length-1] = null;
}
}
}
//3.遍历数组
for (String[] ss : str) {
for (String element : ss) {
System.out.println(element);
}
}
结果如下:
总结
以上就是今天要讲的内容,本文仅仅简单介绍了二维数组,在二维数组的扩容与删除中有许多一维数组的知识,可以通过一维数组,更好地掌握二维数组。希望对您有所帮助!