JAVA中数组的动态扩容和删除、插入

一.数组的动态扩容

在课堂上我们已经了解到了数组的动态扩容,我们所用的方法是用一个新的数组来覆盖旧的数组,这当然是一种不错的方式,但是我们给数组进行动态扩容其实有两种方法。

1、新数组覆盖旧数组

当我们需要对数组进行扩容时,可以考虑不扩容数组本身,而是通过定义一个容量更大的数组,然后让原数组名称重新等于大数组即可。由于原数组数据在堆中,失去引用会被 GC 自动回收。示例如下:

public static void main(String[] args) {                                 
         int[] arr = {1,3,4};  //定义一个容量为3的数组arr                             
         int[] arr2 =new int[arr.length+1]; //定义一个新数组arr2,容量比arr大1          
           for(int i=0;i<arr.length;i++){//通过循环给新数组赋值                       
               arr2[i]=arr[i];                                              
           }                                                                
         arr = arr2;//新数组覆盖旧数组                                              
         System.out.println(arr.length);//打印结果为4,数组扩容成功                     
   }             

我们可以通过定义的新数组arr2的名称直接覆盖掉旧数组arr,原数组被自动回收,从而实现了数组的扩容,因此我们可以根据这个思路进行数组的动态扩容。目标如下:
定义一个容量为1的数组,将系统输入的内容添加到数组中,并每添加一次对数组进行一次扩容。

public static void main(String[] args) {                              
       Scanner input = new Scanner(System.in);                           
       int[] arr = new int[1];  //定义一个容量为1的数组arr                         
       int i =0;                                                         
       while(true) { //通过死循环来观察多次动态扩容的结果                                 
           int x = input.nextInt();//接收int类型的输入                          
           arr[i] = x;//将输入传递给数组arr                                      
           System.out.println(arr[i]);                                   
           int[] arr2 = new int[arr.length + 1]; //定义一个新数组arr2,容量比arr大1  
           //通过循环对新数组赋值                                                  
           for(int j=0;j<arr.length;j++){                                
               arr2[j] = arr[j];                                         
           }                                                             
           arr = arr2;//新数组覆盖旧数组                                         
           i++;                                                          
           System.out.println(Arrays.toString(arr));//打印数组内的值            
       }                                                                 
   }                        

这是我们已经了解过的方法,那么第二种方法是什么呢?

其实我们也已经遇到过了

2、调用Arrays类实现动态扩容

除了新数组覆盖旧数组的暴力扩容法外,我们还可以通过调用系统自带的java.util.Arrays类中的方法对数组进行动态扩容。Arrays类中实现数组扩容的方法为copyof。(需要导入java.util.Arrays)
copyof方法的扩容原理为使用零复制指定的数组,截断或填充(如有必要),以使副本具有指定的长度,调用格式为Arrays.copyof(原数组名,扩容后的数组大小)。示例如下:
 

public class ArrayTest {                                     
    public static void main(String[] args) {                 
        int[] arr = {1, 3, 4};  //定义一个容量为3的数组arr             
        arr = Arrays.copyOf(arr,7);//将数组arr扩容到7              
        arr[6] = 5; //给扩容后的数组下标6定义一个值                        
        System.out.println(Arrays.toString(arr));//打印新数组     
    }                                                        
}                                 

同样我们也使用Arrays类来实现数组的动态扩容,目标如下:
定义一个大小为1的数组,每次输入三个数字,按从大到小的顺序定义到数组中,数组不够的位置通过Arrays类来实现数组的扩容。

public static void main(String[] args) {                                                   
       Scanner input = new Scanner(System.in);                                                
       int i = 3;                                                                             
       int[] arr = {1, 3, 4};  //定义一个容量为3的数组arr                                               
       while(true) {                                                                          
           System.out.println("请输入三个数字"); //输入要添加的三个数字,分别定义为x1,x2,x3                          
           int x1 = input.nextInt();                                                          
           int x2 = input.nextInt();                                                          
           int x3 = input.nextInt();                                                          
           arr = Arrays.copyOf(arr, arr.length + 3);//将数组arr扩容3,并在扩容的位置分别赋值x1,x2,x3           
           arr[i] = x1;                                                                       
           arr[i+1] = x2;                                                                     
           arr[i+2] = x3;                                                                     
           i = i + 3;                                                                         
           System.out.println(Arrays.toString(arr));//打印新数组                                   
       }                                                                                      
   }                                         

通过上面两种方式我们了解了数组的扩容,那么我们还能不能对数组进行其他的一些操作呢?

答案显然是可以的

二、数组的动态删除

其实,数组的动态删除和数组的动态扩容有着异曲同工之妙。都是创建了一个新数组来实现的。

那么具体是怎么操作的呢?

原理:
1.输入一个被删除数组元素的索引值index
2.根据原来数组的长度-1 创建一个新数组;
3.把原来数组的元素进行等索引位置复制到新数组;
4.在复制过程中进行判断,如果 i < index,则直接将 oldarr[i] 复制到新数组;
如果 i >= index ,则将oldarr [ i + 1] 复制到新数组

代码如下:

int[] arr = {11,22,33};
		System.out.print("删除前:");
		print(arr);

		//进行数组的动态删除
		arr = remove(arr,1);

		System.out.print("删除后:");
		print(arr);
		/*
		动态删除的两个明确:
			返回类型:int[]
			形参列表:int[] oldArr , int index
	*/
	public static int[] remove (int[] oldArr , int index ) {
		//进行数组的非空校验
		if (oldArr == null) {
			System.out.println("错误:数组为空");
			return oldArr;
		}

		//进行非法索引校验
		if (index < 0 || index >= oldArr.length) {
			System.out.println("错误:索引非法");
			return oldArr;
		}

		//根据原来数组的长度创建新数组
		int[] newArr = new int[oldArr.length - 1];

		//进行数组中元素的复制
		for (int i = 0; i < newArr.length; i++) {
			if (i < index) {
				newArr[i] = oldArr[i];
			} else {
				newArr[i] = oldArr[i+1];
			}
		}

		return newArr;
	}


三、数组的动态插入

这就更不用说了,其本质和前面两种操作没有太大区别,我们就直接来看他是如何实现的吧

原理:
1.输入一个插入数组元素的索引值index
2.根据原来数组的长度 +1 创建一个新数组;
3.把原来数组的元素进行等索引位置复制到新数组;
4.在复制过程中进行判断,如果 i < index,则直接将 oldarr [ i ] 复制到 newarr [ i ];
如果 i >= index ,则将oldarr [ i + 1] 复制到新数组 newarr [ i + 1];

代码如下:

//声明并初始化数组
		int[] arr = {11,22,33};
		System.out.print("插入前:");
		print(arr);

		//进行数组的动态插入
		arr = insert(arr,2,55);

		System.out.print("插入后:");
		print(arr);
		/*
		动态插入的两个明确:
		    返回类型:int[]
		    形参列表:int[] oldArr , int index , int num
	*/
	public static int[] insert (int[] oldArr , int index , int num) {
		//进行数组的非空校验
		if (oldArr == null) {
			System.out.println("错误:数组为空");
			return oldArr;
		}

		//进行非法索引校验
		if (index < 0 || index >= oldArr.length) {
			System.out.println("错误:索引非法");
			return oldArr;
		}

		//根据原来数组的长度创建新数组
		int[] newArr = new int[oldArr.length + 1];

		//进行数组中元素的复制
		for (int i = 0; i < oldArr.length; i++) {
			if (i < index) {
				//进行等索引位置复制
				newArr[i] = oldArr[i];
			} else {
				//进行错索引位置复制
				newArr[i + 1] = oldArr[i];
			}
		}

		//将待插入元素存储到新数组的指定索引位置
		newArr[index] = num;

		return newArr;
	}


 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值