12.20_学习Java的day05(详解)

一、数组

1、什么是数组?

或者数组是用来做什么的?
通俗的讲:数组代表一组数据。

数组(array)的定义/概念:

相同数据类型的元素按一定顺序排列的集合;
把有限个(长度固定)类型相同的变量用一个名字命名,以便统一管理他们。
这个统一的名称就是数组名(name)。
每一个元素使用编号来区分它们,这个编号我们称为下标或索引(index)。
这组数据中的每一个数据我们称为元素(element)。
数组中元素的总个数,我们称为数组的长度(length)。

数组的好处:可以使用一个数组名 + 下标,来方便的管理一组数据。

2、如何声明和使用数组?

1、如何声明数组?

声明:define/declare

元素的数据类型[] 数组名;

2、为数组初始化

初始化的工作:
①确定数组的长度,即这个数组要存储几个元素
②每一个元素的值是多少

初始化有两种方式:
①动态初始化的方式:
数组名 = new 元素的数据类型[长度];
注意:
长度必须是int值,不能超过int范围;
此时数组的元素都是默认值。

3、如何表示数组的一个元素

格式:数组名[下标]
下标的范围:[0] ~ [数组的长度-1]
例如:长度为5的数组的下标范围[0,4]

4、数组的元素有默认值

byte,short,int,long:默认值0
float,double:默认值0.0
char:默认值是Unicode编码值为0的字符,空字符
boolean:默认值是false
引用数据类型:默认值是null
String是引用数据类型

5、如何为元素赋值

数组名[下标] = 值;

例如:
数组名[下标] = 常量值; 用常量值为元素赋值
数组名[下标] = input.nextInt();等 从键盘接收值为元素赋值
数组名[下标] = Math.random(); 使用表达式为元素赋值
数组名[下标] = a + b; 使用表达式为元素赋值

class DefineAndUseArray{
	//args是一个数组,元素的类型是String
	public static void main(String[] args){
		//现在需要存储一组学员的成绩
		int[] scores;
		
		//现在需要存储一组学员的姓名
		String[] names;
		
		//现在需要存储一组学员的体重
		double[] weights;
		
		//现在需要存储26个小写英文字母
		char[] letters;
		
		//System.out.println(scores);//错误:可能尚未初始化变量scores
		
		//为scores这个数组进行初始化
		//长度指定为5
		scores = new int[5];
		
		System.out.println(scores);//[I@15db9742
		/*
		数组名中实际存储的是这个数组在堆中的首地址,
		但是打印出来的不是地址,因为JVM不对外暴露内存的地址信息,
		实际显示的是数组对象的信息:数组的标记 + 元素的类型 + @ + 数组对象的hashCode值的十六进制形式
		数组的标记:一维数组是[
		元素的类型:int,I
		数组对象的hashCode值的十六进制形式:可以暂时理解为一个对象的编码值,如同一个人的身份证号码一样
		*/
		
		names = new String[5];
		System.out.println(names);
		/*
		[Ljava.lang.String;@6d06d69c
		数组的标记:一维数组是[
		元素的类型:String,Ljava.lang.String;
		*/
		
		System.out.println("第一个同学的成绩:" + scores[0]);//0
		System.out.println("第二个同学的成绩:" + scores[1]);//0
		
		System.out.println("第一个同学的姓名:" + names[0]);//null
		System.out.println("第二个同学的姓名:" + names[1]);//null
		System.out.println("--------------------------");
		
		scores[0] = 89;
		names[0] = "张三";
		System.out.println("第一个同学的成绩:" + scores[0]);
		System.out.println("第一个同学的姓名:" + names[0]);
		
		java.util.Scanner input = new java.util.Scanner(System.in);
		System.out.print("请输入第二个同学的姓名:");
		names[1] = input.next();
		
		System.out.print("请输入第二个同学的成绩:");
		scores[1] = input.nextInt();
		
		System.out.println("第二个同学的成绩:" + scores[1]);
		System.out.println("第二个同学的姓名:" + names[1]);
	}
}

初始化有两种方式:

①动态初始化的方式:

数组名 = new 元素的数据类型[长度];
注意:
长度必须是int值,不能超过int范围;
此时数组的元素都是默认值。

②静态初始化的方式:

数组名 = new 元素的类型[]{元素的值列表};
注意:
长度由列出的元素的个数决定;
此时元素的元素有具体的值;
此时右边的[]中不能再长度了

class DefineAndUseArray2{
	public static void main(String[] args){
		//现在需要存储一组学员的成绩
		int[] scores;
		
		//为scores数组初始化
		scores = new int[]{89,80,67,95,100};
		
		System.out.println("第一个同学的成绩:" + scores[0]);
		System.out.println("第二个同学的成绩:" + scores[1]);
		System.out.println("第三个同学的成绩:" + scores[2]);
		System.out.println("第四个同学的成绩:" + scores[3]);
		System.out.println("第五个同学的成绩:" + scores[4]);
		
		/*
		数组的长度为5,下标的范围是[0,4],超过这个范围就会报错
		ArrayIndexOutOfBoundsException:数组下标越界异常
		*/
	//	System.out.println("第六个同学的成绩:" + scores[5]);//java.lang.ArrayIndexOutOfBoundsException: 5
	}
}

声明与初始化在一句完成

class DefineAndUseArray3{
	public static void main(String[] args){
		//动态初始化
		int[] scores = new int[5];
		
		//静态初始化
		//int[] grades = new int[]{89,80,67,95,100};
		int[] grades = {89,80,67,95,100};//可以省略new int[]
		
		/*可以*/
		int[] grades;
		grades = new int[]{89,80,67,95,100};
		
		/*不可以*/
		//int[] grades;
		//grades = {89,80,67,95,100}; //如果和声明不再一句,不能省略右边的new int[]
	}
}

数组的遍历:

遍历:按个看/访问使用数组元素

使用for循环遍历最合适。
for(int i=0; i<数组的长度; i++){
数组名[i]表示一个元素
}

如何表示数组的长度?
数组名.length

class ArrayIterate{
	public static void main(String[] args){ 
		int[] grades = {89,80,67,95,100};
		
		//for(int i=0; i<5; i++){
		//	System.out.println("第" + (i+1) + "个同学的成绩:" + grades[i]);
		//}
		
		for(int i=0; i<grades.length; i++){
			System.out.println("第" + (i+1) + "个同学的成绩:" + grades[i]);
		}
	}
}
class ArrayIterate2{
	public static void main(String[] args){ 
		int[] grades = new int[5];
		
		java.util.Scanner input  = new java.util.Scanner(System.in);
		for(int i=0; i<grades.length; i++){
			System.out.print("请输入第" + (i+1) + "个同学的成绩:");
			grades[i] = input.nextInt();
		}
		
		for(int i=0; i<grades.length; i++){
			System.out.println("第" + (i+1) + "个同学的成绩:" + grades[i]);
		}
	}
}

回忆:
变量:
代表内存的一块存储区域

二、数组的存储

1、数组:

代表内存中的一整块存储区域,一整块连续的存储区域

2、JVM将内存分为几块

(1)方法区:用来存储被加载的类的代码等信息 ,后面讲解面向对象时,还会再细说
(2)虚拟机栈:Java方法的局部变量
例如:
public static void main(String[] args){
int[] arr = {10,20,30,40};
int age = 29;
String name = “张三”;
}
局部变量有arr,age,name
(3)本地方法栈:本地方法(后面会将,它是C/C++语言的代码)的局部变量
(4)堆:存储实例对象,记住凡是new出来的,都在堆
例如:
public static void main(String[] args){
int[] arr = {10,20,30,40};
int age = 29;
String name = “张三”;
java.util.Scanner input = new java.util.Scanner(System.in);
}
在堆中的有:{10,20,30,40};,“张三”; new java.util.Scanner(System.in);
(5)程序计数器:存储当前线程(后面在多线程部分讲解)下一条指令

今天要讨论的是虚拟机栈和堆

3、数组的存储:

(1)数组在堆中申请一整块连续的空间
(2)数组名存储的是首地址
(3)下标是该元素距离首地址间隔的单元格
所以第一个元素的下标是0

class ArraySave{
	public static void main(String[] args){
		int[] arr = {10,20,30,40};
		
		int[] array;
		
		array = new int[5];
		
		array[0] = 23;
	}
}

数组的基础算法:

1、在数组中进行统计分析:

总和、平均值、偶数的个数、素数的个数。。。

2、在数组中查找

(1)顺序查找
(2)二分查找(后面再讲)

3、数组的最值查找

(1)找最大值/最小值
(2)找最大值/最小值,及其下标

class MaxInArray{
	public static void main(String[] args){
		int[] arr = {3,5,1,7,4};
		
		//查找arr中的最大值
		/*
		思路:
		(1)先假设第一个元素最大/小,让第一个元素先上“擂台”
		(2)后面的元素一一和“擂台”上的元素比较,如果比它大/小,就替换“擂台”上的元素		
		*/
		int max = arr[0];
		for(int i=1; i<arr.length; i++){
			if(arr[i] > max){
				max = arr[i];
			}
		}
		System.out.println("最大值是:" + max);
	}
}
class MaxIndex{
	public static void main(String[] args){
		int[] arr = {3,5,1,7,4};
		
		//查找arr中的最大值
		/*
		思路:
		(1)先假设第一个元素最大/小,让第一个元素先上“擂台”
		(2)后面的元素一一和“擂台”上的元素比较,如果比它大/小,就替换“擂台”上的元素		
		*/
		int max = arr[0];
		int index = 0;
		for(int i=1; i<arr.length; i++){
			if(arr[i] > max){
				max = arr[i];
				index = i;
			}
		}
		System.out.println("最大值是:" + max);
		System.out.println("最大值的下标是:" + index);
	}
}
class MaxIndex_2{
	public static void main(String[] args){
		int[] arr = {3,5,1,7,4};
		
		//查找arr中的最大值
		/*
		思路:
		(1)先假设第一个元素最大/小,让第一个元素先上“擂台”
		(2)后面的元素一一和“擂台”上的元素比较,如果比它大/小,就替换“擂台”上的元素		
		*/
		int index = 0;//index记录的是擂台上的元素的下标
		for(int i=1; i<arr.length; i++){
			if(arr[i] > arr[index]){
				index = i;
			}
		}
		System.out.println("最大值是:" + arr[index]);
		System.out.println("最大值的下标是:" + index);
	}
}

4、数组的排序

(1)冒泡排序

排序算法有很多种:
冒泡排序不是最优的排序,但是是最基础的排序,所有编程语言的学习都从冒泡开始。

目的:实现从小到大
冒泡排序:
(1)从左往右,把大的往右移动
(2)从右往左,把小的往左移动

class BubbleSort{
	public static void main(String[] args){
		int[] arr = {34,24,89,45,2};
		
		//排序:实现从小到大排序
		//选择:从左往右,把大的往右移动
		/*
		第一轮:
			目标:把当前未排序中最大的,移动到未排序元素的最右边
			做法:通过相邻元素比较,如果左边的元素比右边的元素大,就交换
			
			第一次:arr[0]>arr[1]成立,交换arr[0],arr[1],结果{24,34,89,45,2}
			第二次:arr[1]>arr[2]不成立,不换
			第三次:arr[2]>arr[3]成立,交换arr[2],arr[3],结果{24,34,45,89,2}
			第四次:arr[3]>arr[4]成立,交换arr[3],arr[4],结果{24,34,45,2,89}
		
		第二轮:
			未排序:{24,34,45,2}
			目标:把当前未排序中最大的,移动到未排序元素的最右边
			做法:通过相邻元素比较,如果左边的元素比右边的元素大,就交换
			
			第一次:arr[0]>arr[1]不成立,不换
			第二次:arr[1]>arr[2]不成立,不换
			第三次:arr[2]>arr[3]成立,交换arr[2],arr[3],结果{24,34,2,45,89}
			
		第三轮:
			未排序:{24,34,2}
			目标:把当前未排序中最大的,移动到未排序元素的最右边
			做法:通过相邻元素比较,如果左边的元素比右边的元素大,就交换
			
			第一次:arr[0]>arr[1]不成立,不换
			第二次:arr[1]>arr[2],成立,交换arr[1],arr[2],结果{24,2,34,45,89}
		
		第四轮:
			未排序:{24,2}
			目标:把当前未排序中最大的,移动到未排序元素的最右边
			做法:通过相邻元素比较,如果左边的元素比右边的元素大,就交换
			
			第一次:arr[0]>arr[1]成立,交换arr[0]与arr[1],结果{2,24,34,45,89}
			
		总结:(1)5个元素比较4轮==>n个元素,需要n-1轮
			(2)每一轮比较很多次,
				例如:5轮,第一轮,4次
				例如:5轮,第二轮,3次
				例如:5轮,第三轮,2次
				例如:5轮,第四轮,1次
			(3)相邻元素:arr[j]与arr[j+1]  或arr[j-1]与arr[j]		

		重复:重复n-1轮,每一轮重复比较很多次
		      结构:双重循环,外循环控制轮数,内循环控制每一轮比较的次数
		*/
		//外循环控制轮数  假设arr.length=5, i=1,2,3,4
		for(int i=1; i<arr.length; i++){
			//内循环控制次数
			/*
			当i=1,需要4次,j=0,1,2,3	j<arr.length-i
			当i=2,需要3次,j=0,1,2
			当i=3,需要2次,j=0,1
			当i=4,需要1次,j=0
			相邻元素:arr[j]与arr[j+1]
			
			当i=1,需要4次,j=1,2,3,4
			当i=2,需要3次,j=1,2,3
			当i=3,需要2次,j=1,2
			当i=4,需要1次,j=1
			相邻元素:arr[j-1]与arr[j]				
			*/
			//选择j从0开始
			for(int j=0; j<arr.length-i; j++){
				if(arr[j] > arr[j+1]){
					//交换arr[j]与arr[j+1]
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		
		//显示结果
		System.out.print("排序后:");
		for(int i=0; i<arr.length; i++){
			System.out.print(arr[i] + " ");
		}
	}
}

维度:

一维:一个维度,行
int[] arr = {1,2,3,4,5};
二维:两个维度,行和列
1,2,3,4,5
5,6,7,8
9,4,5,6,4
三行,每一行的列数不同,第一行有5列,第二行有4列,第三行有5列

二维数组:类似于二维表。

1、如何声明二维数组?

回忆:一维数组的声明格式:元素的数据类型[] 数组名;

二维数组的声明格式: 元素的数据类型[][] 数组名;

2、为数组初始化?

(1)静态初始化
回忆:一维数组的静态初始化:
数组名 = new 元素的数据类型[]{元素的值列表};

二维数组的静态初始化:
		**数组名 = new 元素的数据类型[][]{{第一行的元素值列表},{第二行的元素值列表}。。。};**

(2)动态初始化

3、如何表示二维数组的每一个部分

(1)二维数组的长度,即二维数组的总行数:数组名.length
(2)二维数组的某一行:数组名[行下标]
行下标的范围:[0, 数组名.length-1]
(3)二维数组的某一行的长度: 数组名[行下标].length
因为二维数组的一行,是一个一维数组
(4)二维数组的一个元素:
数组名[行下标][列下标]
列下标的范围:[0, 数组名[行下标].length-1]

4、数组的遍历

for(int i=0; i<二维数组的总行数; i++){
for(int j=0; j<每一行的总长度; j++){
二维数组名[i][j]是元素
}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值