二维数组(拷贝/扩容/删除)——Java

目录

前言

一、二维数组的声明及初始化

1.二维数组的声明

2.二维数组的初始化

2.1静态初始化

2.2动态初始化

二、访问数组元素

1.设置元素

1.1 设置元素

1.2 案例​​​​​​​

2.遍历数组

2.1 嵌套for循环遍历

2.2 嵌套foreach遍历

三、二维数组的拷贝

1.浅拷贝

2.深拷贝

2.1 for循环嵌套拷贝

2.2 for循环+Arrays工具类中拷贝方法

四、二维数组的扩容

1.扩容二维数组中的一维数组的数量

2. 扩容二维数组中的一维数组的容量

 五、二维数组的删除

1.删除二维数组中某个一维数组

1.1 删除方式1

 1.2  删除方式2

 2.删除二维数组中的一维数组中的某个元素

总结



前言

二维数组包含多个一位数组,将使用多个下标访问数组元素,同样下标是从0开始的。可以结合一维数组的基本知识来学习了解二维数组。在二维数组中的扩容与删除中,可以找到许多与一维数组的扩容与删除的相似之处。

可以通过下方链接温习一些简单的一维数组的知识,温故而知新。

一维数组 ——Java_康凯哇咔咔的博客-CSDN博客


提示:以下是本篇文章正文内容,下面案例可供参考

一、二维数组的声明及初始化

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);
   	}
}

结果如下:


总结

以上就是今天要讲的内容,本文仅仅简单介绍了二维数组,在二维数组的扩容与删除中有许多一维数组的知识,可以通过一维数组,更好地掌握二维数组。希望对您有所帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值