课程大纲 | 课程内容 | 学习效果 | 掌握目标 |
数组概念 | 了解 | 了解数组概念 | |
数组定义和初始化 | 掌握 | 熟练掌握数组定义和初始化方式 | |
数组 | 访问数组元素 | 掌握 | 熟练掌握数组元素的访问方式 |
数组内存图 | 重点掌握 | 会画数组内存图 | |
数组排序 | 掌握 | 熟练掌握冒泡选择排序 | |
二维数组 | 了解 | 了解二维数组的定义和使用方式 |
现在需要统计班上每一个同学的名字,假设班上有30名同学,用前面所学的知识,首先需要声明30个变量来分别记录每一个同学的名字,这样做显然很麻烦,为了解决这类问题,Java就提供了数组供我们使。
数组就是存储多个数据类型一致的变量(元素)的容器。
数组既可以存储基本数据类型,也可以存储引用数据类型。
①没有数组:存在多个变量,需要声明多个变量的名称,这些名称之间没有什么关联,想访问所有的变量,比较困难。
②有了数组:只需要有一个数组容器的名称,容器里面有通过数字表示位置,同时这些数字位置有规律,结合数组名称,非常容易的去访问所有的变量。数字的位置可以称为索引,数组在内存中开辟了一块连续的存储空间。
格式1:数据类型[] 数组名;(推荐使用) 如:int [] nums;
格式2:数据类型 数组名[];(是为了兼容C语言)如int nums[];
【示例代码】
public static void main(String[] args) {
//数组的定义: 数据类型[] 数组名
int[] aa; //定义了一个int类型的数组——这个数组中只能存放int类型的数据
String[] ss; //定义了一个String[]数组——只能存放String类型的数据
double[] dd;
//另一种定义方法(不常用) 为了兼容C语言的写法
int aaa[];
String sss[];
/*
int x;
System.out.println(x); //变量定义完,不赋值,是不能使用的!!!
*/
}
所谓的初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素分配内存空间。
【注意】:java中的数组必须先初始化才能使用。
(1)动态初始化
【格式】:元素数据类型[] 数组名 = new 元素数据类型[数组长度];如int[] nums = new int[30];//数组长度其实就是数组中元素的个数
详细的解释
1.元素的数据类型:数组中数据的类型,用于决定每个空间的大小。
2.元素:数组中的数据,数组中的变量。
3.[]:表示一个一维数组 [][]:二维数组
4. = :赋值号,将数组的地址,赋值给数组名称
5.new:开辟内存空间
6.数组长度/数组容器的大小:可以存储数据的个数。
【注意】:数组长度指定之后不可以改变
【举例】: int[] arr = new [3];//解释:定义了一个int类型的数组,这个数组可以存放3个int类型的值。
【示例代码】
public static void main(String[] args) {
// 数组长度指定后,不能改变
int[] aa = new int[5]; // 初始化数组,并制定数组的长度为5(这个数组中最多可以存放5个int类型数据)
aa[0] = 5;
String[] ss = new String[10];
System.out.println(arr);//[I@15db9742
}
(2)静态初始化
【格式】:数组类型[] 数组名 = new 数组类型[]{元素1,元素2,...};
如int[] nums = new int[]{1,2,3,4,5};或者简化为int[] nums = {1,2,3,4,5};
【举例】int[] arr = new int[]{1,2,3};//解释:定义了一个int类型的数组,这个类型可以存放三个int类型的值,并且值分别是1,2,3;
【注意】
1.不要在第二个[方括号中,不要写数组的个数。初始化时不允许动静结合。
2.元素值列表,如果多个元素,中间使用逗号分隔,写了几个元素,就分配多大的空间
3.元素值列表中的元素类型要和定义的类型保持一致。
【简化格式】:数组类型[] 数组名 = {元素1,元素2,...};
【举例】:int[] arr = {1,2,3};
【示例代码】
public static void main(String[] args) {
int[] aa = new int[]{4,1,3,8,8,9}; // 创建了一个6个长度的数组,并完成了赋值
String[] ss = new String[]{"aaa","bbb","ccc"};
//不要动静结合
//int[] arr2 = new int[3]{10,20,30};
//元素值列表中的元素类型要和定义的类型保持一致。
//int[] arr3 = new int[]{1.0,2.0};
//简化格式
int[] aaa = {1,2,4,5,8,9}; //创建了一个6个长度的数组,并完成了赋值
String[] sss = {"aaa","bbb","ccc"};
}
【索引】:每一个存储到数组的元素,都会自动拥有一个编号,从0开始,这个自动编号称为数组索引(index)(下标),可以通过数组的索引访问到数组中的元素。
【格式】:数组名[索引]
【数组的长度属性】:每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度。 语句为:数组名.length,属性length的执行结果是数组的长度,int 类型结果。
【索引访问数组中的元素】:数组名[索引值] = 数值; 为数组中的元素赋值。 变量名 = 数组名[索引值];获取数组中的元素
【示例代码】
public class Demo04_访问数组元素 {
public static void main(String[] args) {
/*
默认值:
byte ----0
short -----0
long --------0
int ---------- 0
double ---- 0.0
char------- 空字符
String ----- null(空值)
*/
int[] aa = new int[5]; // 动态初始化的数组,没有给数组中赋值过,
//数组中的元素会使用相应类型的默认值
int x = aa[0]; // 数组的第一个元素
System.out.println(x);
System.out.println(aa[1]);
System.out.println(aa[2]);
double[] dd = new double[5];
System.out.println(dd[0]);
System.out.println(dd[1]);
/*
char[] cc = new char[5];
System.out.println(cc[0]);
System.out.println(cc[1]);
*/
String[] ss = new String[5];
System.out.println(ss[0]);
System.out.println(ss[1]);
}
} System.out.println(ss[1]);
}
}
【示例代码】
public class Demo05_访问数组元素2 {
public static void main(String[] args) {
/*
int[] aa = new int[5];
aa[0] = 1; // 给数组赋值
aa[1] = 3;
aa[2] = 5;
aa[3] = 7;
aa[4] = 9;
//aa[5] = 10
*/
int[] aa = {2,4,6,8,9};
System.out.println(aa[2]);
System.out.println(aa[3]);
System.out.println(aa[4]);
//System.out.println(aa[5]); 数组索引越界
}
}
内存是计算机中的重要元件,可以用来给程序临时存储数据。我们编写的程序,必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
【 JVM的划分】
为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
①JVM是执行java程序的容器,空间很大,需要划分不同的空间,不同的功能,需要使用不同的区域来指定完成。分为:【栈内存,方法区,堆内存】,本地方法区,程序计数器。
②栈内存【常用】:也叫方法栈,方法运行时使用的内存,比如main方法运行,进入方法栈中执行,用于执行方法,每个方法单独分配一段空间,称为栈帧,把给方法分配内存空间,形象的称为“进栈”。特点:先进后出。
③堆内存【常用】:用于存放数组、对象等数据量较大的数据,一般都是引用数据类型,new来创建的,都存储在堆内存。
④方法区【常用】:用于存储类的字节码对象,存储可以运行的class文件,存储常量(final修饰),存储静态变量。
⑤本地方法区:用于执行本地方。C语言,C++语言方法就是本地方法。
⑥程序计数器:用于控制程序的执行、控制程序执行到哪一行代码。
(1)一个数组的内存图
public static void main(String[] args) {
int[] arr = new int[3];
System.out.println(arr);//[I@5f150435
}
[I@15db9742 以上方法执行,输出的结果是[I@5f150435,这个是什么呢?是数组在堆内存中的地址。
[;表示一个一维数组。
I:表示数组中存放的数据类型为int类型。
15db9742:表示一个16进制的地址,表示数组中起始的内存地址值。数组名称arr可以存数组
【注意】:new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址。
【程序执行流程】: 1,main方法进入方法栈执行 2,创建数组,JVM会在堆内存中开辟空间,存储数组 3.数组在内存中会有自己的内存地址,以十六进制数表示,0X1AB 4.数组中有3个元素,默认值是0 5.JVM将数组的内存地址复制给引用数据类型变量arr 6.变量arr保存的是数组内存中的地址,而不是一个具体的数值,因此称为引用数据类型
(2)两个数组的内存图
public static void main(String[] args){
int[] arr1 = {1,2,3};
int[] arr2 = {13.,23,43};
arr1 = arr2;
}
(3)两个变量指向一个数组
public static void main(String[] args) {
// 定义数组,存储3个元素
int[] arr = new int[3];
// 数组索引进行赋值
arr[0] = 5;
arr[1] = 6;
arr[2] = 7;
// 输出3个索引上的元素值
System.out.println(arr[0]);//5
System.out.println(arr[1]);//6
System.out.println(arr[2]);//7
// 定义数组变量arr2,将arr的地址赋值给arr2
int[] arr2 = arr;
arr2[1] = 9;
System.out.println(arr2[1]);//9
System.out.println(arr[1]);//?9
}
每个数组的索引都有一个范围,即0~length-1。在访问数组的元素时,索引不能超出这个范围,否则程序会报错,如下所示:
public static void main(String[] args) {
int[] arr = new int[4]; // 定义一个长度为4的数组
System.out.println("arr[4]=" + arr[4]); // 通过角标4访问数组元素
}
上面运行结果中所提示的错误信息是数组越界异常ArrayIndexOutOfBoundsException,出现这个异常的原因是数组的长度为4,其索引范围为0~3,而上述代码中的第4行代码使用索引4来访问元素时超出了数组的索引范围。
所谓异常指程序中出现的错误,它会报告出错的异常类型、出错的行号以及出错的原因。
①遍历:一个个元素进行访问
②方式:通过循环,访问到数组中的所有的索引,通过索引,访问到对应的元素。
③索引:范围0~数组长度-1 长度:数组名称.length
【示例代码】
/*
遍历数组
*/
class TraverseArr {
public static void main(String[] args) {
//定义数组并初始化
int[] arr = {16,12,88,6,38,42,66};
//调用遍历方法
traverse(arr);
}
/*
定义遍历的方法
*/
public static void traverse(int[] arr){
for(int i=0; i
①给定一个数组,求出数组的最大值。
②思路:擂台思想
【示例代码】
/*
数组的最值
*/
class GetArrMaxAndMin {
public static void main(String[] args) {
//定义数组并初始化
int[] arr = {16,12,88,6,38,42,66};
//调用方法
int max = getMax(arr);
System.out.println("max="+max);
System.out.println("min="+getMin(arr));
}
//定义求最大值的方法
public static int getMax(int[] arr){
int max = arr[0];
for(int i=0; i arr[i] ? max : arr[i];
}
return max;
}
//定义求最小值的方法
public static int getMin(int[] arr){
int min = arr[0];
for(int i=0; i arr[i]){
min = arr[i];
}
}
return min;
}
}
①数组反转的操作:第一个元素与最后一个元素进行交换,第二个元素与倒数第二个元素进行交换,以此类推。
思路一:
思路二
【示例代码】
/*
数组的反转
*/
class ReverseArray {
public static void main(String[] args) {
//数组的定义 初始化
int[] arr = {2,1,10,5,3};
//反转前遍历数组
traverseArr(arr);
//反转数组
reverseArr(arr);
//反转后遍历数组
traverseArr(arr);
reverseArray(arr);
//反转后遍历数组
traverseArr(arr);
}
/*
定义方法:反转数组
*/
public static void reverseArr(int[] arr){
for(int i=0,j=arr.length-1;i
①给定一个数组,找到指定值的索引。
②遍历数组,判断每个元素是否与要找的元素值相等,如果相等,那么就返回当前元素的索引,如果没有找到,返回-1
【示例代码】
/*
查找数组元素
*/
import java.util.Scanner;
class FindElement_Array {
public static void main(String[] args) {
//数组的定义 初始化
int[] arr = {2,1,10,5,3};
//创建Scanner对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入要查找的数字:");
int num = sc.nextInt();
int index = 0;
for(int i=0; i
①选择排序
【示例代码】
//数组的选择排序:从小到大
class SelectSort_Array {
public static void main(String[] args) {
int[] arr = {1,23,4,33,53,21,66,32,88,66};
//排序前 遍历
traverseArr(arr);
//选择排序
selectSort(arr);
//排序后 遍历
traverseArr(arr);
}
//定义选择排序
public static void selectSort(int[] arr){
for(int i=0; iarr[j]){
swapArr(arr,i,j);
}
}
}
}
//定义遍历的方法
public static void traverseArr(int[] arr){
for(int i=0; i
②冒泡排序
【示例代码】
//数组的冒泡排序:从小到大
class BubbleSort_Array {
public static void main(String[] args) {
int[] arr = {1,23,4,33,53,21,66,32,88,66};
//排序前 遍历
traverseArr(arr);
//选择排序
BubbleSort(arr);
//排序后 遍历
traverseArr(arr);
}
//定义选择排序
public static void BubbleSort(int[] arr){
for(int i=0; iarr[j+1]){
swapArr(arr,j,j+1);
}
}
}
}
//定义遍历的方法
public static void traverseArr(int[] arr){
for(int i=0; i
二维数组就是关于数组的数组。
int[][] a = new int[4][]; 的含义?
目前的对象中只有4个指针,准备指向4个数组。
int[][] a = new int[4][];
a[0] = new int[3];
a[1] = new int[3];
a[2] = new int[3];
a[3] = new int[3];
可以简写为:
int[][] a = new int[4][3];
1.二维数组:一维数组的嵌套,数组的每个元素,又是一个数组。
2.定义格式:
数据类型[][] 数组名 = new 数据类型[行的大小][列的大小];
3.创建了一个一维数组,每行的内容就是一维数组的内容。每行的内容又是一个数组。
4.静态初始化
int[][] arr = { {1,2},{30},{1,2,3,4},null,{}}
5.动态初始化int[][] arr = new int[行的长度][];
class Demo02 {
public static void main(String[] args) {
int[][] arr = new int[3][4];
//打印地址
System.out.println(arr);//[[I@15db9742
System.out.println(arr[0]);//[I@6d06d69c
System.out.println(arr[1]);//[I@7852e922
System.out.println(arr[2]);//[I@4e25154f
//打印值
System.out.println(arr[0][1]);//0
arr[0][1] = 5;
System.out.println(arr[0][1]);//5
int[][] arr2 = new int[3][];
System.out.println(arr2);//[[I@70dea4e
System.out.println(arr2[0]);//null
int[] arr3 = {1,2,4,5};
arr2[0] = arr3;//传地址
System.out.println(arr2[0][2]);//4
}
}
遍历:嵌套循环,外层循环控制行,内存循环控制列
/*
二维数组的遍历
*/
class Demo03 {
public static void main(String[] args) {
int[][] arr = {
{1,2},{30},{1,2,3,4},null,{}};
for(int i=0;i
1 复习本周内容
2.分别定义方法,求一个整数数组的最大值、最小值、平均值和所有数组元素的和(4个方法)
//2.分别定义方法,求一个整数数组的最大值、最小值、平均值和所有数组元素的和(4个方法)
class Homework02 {
public static void main(String[] args) {
int[] arr = {3,6,5,2,6,10};
System.out.println("max="+getMax(arr));
System.out.println("min="+getMin(arr));
System.out.println("sum="+getSum(arr));
System.out.println("avg="+getAvg(arr));
}
//定义最大值的方法
public static int getMax(int[] arr){
int max = arr[0];
for(int i=1; iarr[i] ? max : arr[i];
}
return max;
}
//定义最小值的方法
public static int getMin(int[] arr){
int min = arr[0];
for(int i=1; i
3.将一个已知数组 int[] a = {11,23,1,5,6,89} 中的元素,复制到一个新数组中
//3.将一个已知数组 int[] a = {11,23,1,5,6,89} 中的元素,复制到一个新数组中
class Homework03 {
public static void main(String[] args) {
int[] a = {11,23,1,5,6,89};
int[] arr = new int[a.length];
arr = a;
traverse(arr);
}
//定义遍历的方法
public static void traverse(int[] arr){
for(int i=0; i
4. 产生1到10之间的随机数,把这些随机数装入一个10个长度的数据。要求,数组中数据不能重复
import java.util.Random;
class Homework06 {
public static void main(String[] args) {
Random random = new Random();
int[] arr = new int[10];
int r;
for(int i=0;i