【Java学习笔记】15 - 数组 (初始化、赋值机制、拷贝、扩容、缩减)

目录

一、数组

1.数组介绍入门

2.数组的使用

 1) 动态初始化

2)动态初始化

3)静态初始化

3.数组使用细节和注意事项

4.数组案例

5.数组赋值机制

1.值传递和引用传递的区别

2.练习,数组拷贝

        3.练习 数组反转

        4.数组扩容

        ​​​​​​​        ​编辑

        5.数组缩减


一、数组

                

传统方法只能使用定义一个个变量的方式实现

public class Array01{
	public static void main(String[] args){
		int a = 3, b = 5 ,c = 1,e = 2,f = 50;
		double d = 3.4;
		double sum =( a + b + c + d + e + f ) / 6.0;
		System.out.println(sum);
	}
}

                

         但当变量过多时,会更难实现,所以需要使用数组来实现

1.数组介绍入门

        数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型,即数组就是一组数据

public class Array01{
	public static void main(String[] args){
		double[] d = {3,5,1,3.4,2,50};//[]表示声明的是double类型的数组, d为数组名
		//{}表示数组内的元素,例如3.4是第3个元素
		double sum = 0.0;
		for(int i = 0;i<6;i++){
			System.out.println("第" + i + "个元素的值为" + d[i]);
			sum += d[i];
		}
		System.out.println(sum);
		System.out.println(sum / 6.0);
	}
}

                

        注意,数组内的第几个元素是从0开始的,如果从1 开始遍历会报错,无法遍历到第六个

                                

        在JAVA中,可以通过数组名.length 可以得到数组的长度

public class Array01{
	public static void main(String[] args){
		double[] d = {3,5,1,3.4,2,50};//[]表示声明的是double类型的数组, d为数组名
		//{}表示数组内的元素,例如3.4是第3个元素
		System.out.println(d.length);
		double sum = 0.0;
		for(int i = 0;i < d.length;i++){ //d.length为数组的长度,为6
			System.out.println("第" + i + "个元素的值为" + d[i]);
			sum += d[i];
		}
		System.out.println(sum);
		System.out.println(sum / 6.0);
	}
}

        

2.数组的使用

 1) 动态初始化

        数组的定义

        数据类型[] 数组名 = new 数据类型[大小] 或者可以写成

        数据类型 数组名[] = new 数据类型[大小]  //创建了一个数组 名字为a,存放5个int

这是定义数组的一种方法

                

数组的引用

        数组名[下标/索引] 比如:你要使用a数组的第三个数 a[2] (数组的下标从0开始)

import java.util.Scanner;//
public class Array02{
	public static void main(String[] args){
		double[] scores = new double[5];//数组初始化
		for(int i = 0 ; i < scores.length;i++){//遍历数组 输入
			System.out.println("请输入第" + (i + 1)+ "个人的成绩");//i + 1 只是方便阅读
			Scanner myScanner = new Scanner(System.in);
			scores [i] = myScanner.nextDouble();
		}
		System.out.println("五个人的成绩分别为");
		for(int i = 0 ; i < scores.length;i++){//遍历数组 输出
			System.out.printf("%-12.1f",scores[i]);//输出到一行上 注意是浮点类型
		}
	}
}

                

2)动态初始化

先声明数组

        语法:数据类型 数组名[] ;也可以 数据类型[] 数组名;

        int a[]; 或者 int[] a;

 然后创建数组

        语法:数组名 = new 数据类型[大小];

        a = new int[10];

import java.util.Scanner;//
public class Array02{
	public static void main(String[] args){
		// double[] scores = new double[5];
		double[] scores;//此时scores 是 null
		scores = new double[5];
		for(int i = 0 ; i < scores.length;i++){
			System.out.println("请输入第" + (i + 1)+ "个人的成绩");
			Scanner myScanner = new Scanner(System.in);
			scores [i] = myScanner.nextDouble();
		}
		System.out.println("五个人的成绩分别为");
		for(int i = 0 ; i < scores.length;i++){
			System.out.printf("%-12.1f",scores[i]);
		}
	}
}
3)静态初始化

初始化数组

        语法:数据类型 数组名[] = {元素值,元素值,....};

????有bug还是咋的 为啥这个写着写着不保存呢。

3.数组使用细节和注意事项

特别注意不能混用的规则,在后面有具体的案例,char[] num = new char[5]; int i = 1; num[] = (char)(‘A’+i);

4.数组案例

public class ArrayExercise{
	public static void main(String[] args){
		char letter[] = new char[25];
		for(int i = 0;i < 25;i++){
			letter[i] = (char)('A' + i);//注意需要进行int强转为char
			System.out.printf("%-2c",letter[i]);
		}
	}
}

        

public class ArrayExercise02{
	public static void main(String[] args){
		int num[] = {4,-1,9,10,23};
		int max = 0;
		int count = 0;
		for(int i = 0;i < num.length;i++){
			if (num[i] > max) {
				max = num[i];
				count = i;
			}
		}
		System.out.println(max + "  " + count);
	}
}

5.数组赋值机制

1.基本数据类类型赋值,这个值就算具体数据,相互不影响 int n1=2;int n2=n1;值传递

2.数组在默认情况下是引用传递,赋的是地址,称作引用传递

        示例

public class ArrayAssign{
	public static void main(String[] args){
		int n1 = 10;
		int n2 = n1;
		n2 = 80;
		System.out.println("n1="+n1);
		System.out.println("n2="+n2);

		int[] arr1 = {1,2,3};
		int[] arr2 = arr1;
		arr2[0] = 10;
		for (int i = 0;i < arr1.length;i++){
		System.out.println("arr1="+arr1[i]);
		System.out.println("arr2="+arr2[i]);
		}

	}
}

               

        出现了很奇怪的现象,改变的是arr2的值,但是arr1也变化了,所以引出值传递和引用传递的区别

1.值传递和引用传递的区别

        1)值传递会找到n1对应的值,然后拷贝值到n2上,所以n2 = 80不会改变n1的值

        2)但是数组引用传递传递的是地址,arr1的地址对在堆里对应一个数据空间,例如0x0011下的三个值是数组的元素1 2 3,而arr2 = arr1值得是指向0x0011地址,所以改变arr2时是改变了0x0011地址下的三个元素,所以arr1对应的地址也会跟着改变。

        即最大的区别,基本数据类型拷贝的是值,而引用数据类型是指向同一数据空间,也就是地址,而不是生成个新地址。

                

2.练习,数组拷贝

        将int[] arr1 = {10,20,30}拷贝到arr2数组,要求数据空间独立

public class Arraycopy{
	public static void main(String[] args){
		int[] arr1 = {10,20,30};
		int[] arr2 = new int[arr1.length];
		for(int i = 0;i < arr1.length;i++){
			arr2[i] = arr1[i];
			System.out.println("arr2=" + arr2[i]);
		}
		arr2[2] = 500;
		for(int i = 0;i < arr1.length;i++){
			System.out.println("arr1=" + arr1[i]);
			System.out.println("arr2=" + arr2[i]);
		}
	}
}

                

                

        3.练习 数组反转

要求:把数组的元素内容反转

                

方法1可以理解为直接交换05 14 23 三次循环,实现arr1.length / 2 循环一半,然后arr1[6 - 1 -i]赋值到中间值上,arr[arr.length - 1 - i] = arr[i] 将0下标的数赋值到5上  temp上然后赋值到arr[i]上,

我使用的是方法2,反序的赋值到新数组arr2上,然后遍历赋值给arr1即可

public class ArrayReverse{
	public static void main(String[] args){
		int[] arr1 = {11,22,33,44,55,66};
		int[] arr2 = new int[arr1.length];
		for(int i = 0;i < arr1.length;i++){
			System.out.printf("arr1=%d  " ,arr1[i]);
		}//打印arr1反转前的数据空间
		System.out.println();
		for(int i = 0;i < arr1.length;i++){
			arr2[i] = arr1[arr1.length - 1 - i];//赋值到中间数组上 arr2[0] = arr1[6 - 1 -0]
//arr2[5] = arr1[6 - 1 -5]  以此交换元素
			System.out.printf("arr2=%d  " ,arr2[i]);
		}
		System.out.println();
		for(int i = 0;i < arr1.length;i++){
			arr1[i] = arr2[i];//随后在一一对应拷贝赋值即可
		}
		for(int i = 0;i < arr1.length;i++){
			System.out.printf("arr1=%d  " ,arr1[i]);//打印
		}
	}
}

        ​​​​​​​        ​​​​​​​

        4.数组扩容

                要求,实现动态的给数组添加元素效果,实现对数组的扩容,元素静态分配int[] arr = {1 2 3},增加的元素直接放在数组最后arr={1 2 3 4},用户可以通过y/n来决定是否继续添加

============错误示范============

import java.util.Scanner;//
public class ArrayAdd{
	public static void main(String[] args){
		Scanner myScanner = new Scanner(System.in);
		int[] arr1 = {1,2,3};
		int enter = 0;
		int i = arr1.length - 1;//最高元素的下标,例如现在是2
		char answer;
		while(true){
			i++;//自增循环 现在需要i就是我们要添加的最高元素的下标,比如第一次添加
			//就是对arr1[3]进行处理
			System.out.println("请输入想添加的整数");
			enter = myScanner.nextInt();
			arr1 = new int[i+1];//但现在没有arr1[3] 所以需要扩大数组长度 注意int[数组长度]
			//而不是下标
			System.out.println("已经成功添加" + enter + "整数到第" + i + "个元素");
			arr1[i] = enter;//此时赋值enter到arr1的第i个元素
			System.out.println("是否继续添加 y/n");
			answer = myScanner.next().charAt(0);
			if(answer == 'n'){
				System.out.printf("现在数组arr1 = ");
				for(int j = 0;j < arr1.length;j++) //循环打印数组
				{
					System.out.printf("%d,",arr1[j]);
				}
				break;
			}
		}
	}
}

                不会做,铸币了        ​​​​​​​       

                 

        难不成要做一个中间变量的数组吗然后循环赋值?也不对,怎么扩大已有的数组长度呢

        还真是,用旧的数组赋值到新的数组上,完全懂啦!然后记得指向同一地址,即上一节的引用赋值

import java.util.Scanner;//
public class ArrayAdd{
	public static void main(String[] args){
		Scanner myScanner = new Scanner(System.in);
		int[] arr1 = {1,2,3};
		int[] arr2;
		int enter = 0;
		int i = arr1.length - 1;//最高元素的下标,例如现在是2
		char answer;
		while(true){
			i++;//自增循环 现在需要i就是我们要添加的最高元素的下标,比如第一次添加
			//就是对arr1[3]进行处理
			System.out.println("请输入想添加的整数");
			enter = myScanner.nextInt();
			// arr1 = new int[i+1];//但现在没有arr1[3] 所以需要扩大数组长度 注意int[数组长度]
			// //而不是下标
			arr2 = new int[i + 1];//改变思路,用旧的小的那个数组赋值到新的大的这个数组上
			for(int j = 0;j < arr1.length;j++) //遍历数组,将arr1拷贝到arr2上 
			//注意,此时的遍历次数应该是arr1的长度而不是arr2的
				{
					arr2[j] = arr1[j];//这里是拷贝赋值,不改变引用的值的大小而是arr2本身
				}
			System.out.println("已经成功添加" + enter + "整数到第" + i + "个元素");
			arr2[i] = enter;//此时赋值enter到arr1的第i个元素
			arr1 = arr2; //引用赋值,关键中的关键,使用该赋值可以让arr1的值指向arr2,此时就有1 2 3 4
			//就不用担心arr1不够大了
			System.out.println("是否继续添加 y/n");
			answer = myScanner.next().charAt(0);
			if(answer != 'y'){
				System.out.printf("现在数组arr1 = ");
				for(int k = 0;k < arr2.length;k++) //循环打印数组
				{
					System.out.printf("%d,",arr1[k]);
				}
				break;
			}
		}
	}
}
        ​​​​​​​        
        5.数组缩减
import java.util.Scanner;//
public class ArrayReduce{
	public static void main(String[] args){
		Scanner myScanner = new Scanner(System.in);
		int[] arr1 = {1,2,3,4,5};
		int[] arr2;
		char answer;
		int i = arr1.length - 1;//最高元素的下标,例如现在是4
		while(true){
			System.out.printf("\n输入 y/n 执行数组删减\n");
			answer = myScanner.next().charAt(0);			
			
			if(answer == 'y'){
				if(i == 0){//判断是否到0  到0即就剩一个元素了
				System.out.printf("已达到最小元素,无法删减,输入n来关闭程序,现在数组arr1=%d\n",arr1[0]);
				continue;
				}
				i--;//下标自减
				arr2 = new int[i + 1];//长度为下标+1
				for(int j = 0;j < arr2.length;j++) //遍历数组,将arr1拷贝到arr2上,拷贝的次数为arr2的长度
				{
					arr2[j] = arr1[j];//这里是拷贝赋值,不改变地址而是arr2本身元素的值
				}
				arr1 = arr2;//指向arr2的地址,销毁旧的arr1数据空间
				System.out.printf("此时数组arr1=");
				for(int k = 0;k < arr2.length;k++) //循环打印数组
				{
					System.out.printf("%-2d",arr1[k]);
				}
			}
			else if(answer == 'n'){
				System.out.printf("\n关闭程序\n");
				break;
			}

		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yinhai1114

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值