本文是课上资料的总结非原创没有转载地址
目录
Java数组
- 变量:内存中一块存储空间,存储数据的基本单元。只能存一个数据
为什么要使用数组?
- 如何存储100名学生的成绩?
- 办法:使用变量存储,重复声明100个double类型变量即可。
- 缺点:麻烦,重复操作过多。
- 如何让100名学生成绩全部+1?
- 办法:100个变量重复相同操作,直至全部完成。
- 缺点:无法进行统一的操作。
1.数组的概念
- 数组概念:一组连续的存储空间,存储多个相同数据类型的值。
- 特点:
- 类型相同
- 长度固定
2.数组的创建
- 声明int数组类型变量定义变量名为a。
- 分配长度为5的连续空间
public class TestCreateArray {
public static void main(String[] args) {
int[] a = new int[5];
}
}
2.1 数组创建语法
- 先声明、再分配空间:
// 先声明、再分配空间:
数据类型[] 数组名;
数组名 = new 数据类型[长度];
- 声明并分配空间:
// 声明并分配空间:
数据类型[] 数组名 = new 数据类型[长度];
- 声明并赋值(繁):
// 声明并赋值(繁):
数据类型[] 数组名 = new 数据类型[]{value1, value2, value3, ...};
- 声明并赋值(简):
// 声明并赋值(简):
数据类型[] 数组名 = {value1, value2, value3, ...}; // 显示初始化,注意:不可换行
2.2 数组的默认值
类型 | 默认值 |
---|---|
整数 | 0 |
小数 | 0.0 |
字符 | \u0000 |
布尔 | false |
其他 | null |
3.数组的下标
- 数组中的每个数据格被称为“数组元素”。
- 对每个元素进行赋值或取值的操作被称为“元素的访问”。
- 访问元素时,需要使用“下标”(从0开始,依次+1,自动生成)。
- 访问语句:
数组名[下标]; // 例如 存:a[0] = 10; 取:a[0];
3.1 使用
public class TestCreateArray {
public static void main(String[] args) {
int[] a = new int[5]; // 创建数组
// 依次赋值
a[0] = 5;
a[1] = 3;
a[2] = 4;
a[3] = 7;
a[4] = 10;
// 依次取值
System.out.println(a[0]);
System.out.println(a[1]);
System.out.println(a[2]);
System.out.println(a[3]);
System.out.println(a[4]);
}
}
- 结果:
5
3
4
7
10
3.2 下标范围
- 数组有效长度:有效下标范围:0~数组长度-1
public class TestCreateArray {
public static void main(String[] args) {
int[] a = new int[5]; // 创建数组 有效下标范围:0~数组长度-1
// 依次赋值
a[0] = 5;
a[1] = 3;
a[2] = 4;
a[3] = 7;
a[4] = 10;
// 依次取值
System.out.println(a[0]);
System.out.println(a[1]);
System.out.println(a[2]);
System.out.println(a[3]);
System.out.println(a[4]);
System.out.println(a[5]); // 访问无效下标,会导致数组下标越界
}
}
- 结果:数组越界异常
java.lang.ArrayIndexOutOfBoundsException:5
4.数组的遍历
数组名.length
可动态获得数组长度。
4.1 for
- 遍历:从头至尾,逐一对数组的每个元素进行访问。
- 使用循环变量
i
充当下标,逐一访问数组中的每个元素。
public class TestVisitArray {
public static void main(String[] args) {
int[] a = new int[5];
a[0] = 5;
a[1] = 3;
a[2] = 4;
a[3] = 7;
a[4] = 10;
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
4.2 增强for(foreach)
- 在JDK1.5之后,Java提供了增强for简化数组或集合的遍历
- 语法:
for (数组元素类型 元素变量 : 数组) {
// 元素变量代表数组中每个元素
}
- 缺点:不能使用下标
5.数组的内存分析
- 程序运行中有两块重要的存储空间【个人感觉非常非常重点】
- 栈
- 存储基础类型数据以及引用类型的地址
- 特点1:空间比较小,存储速度较快 jdk1.5之前256k jdk1.5之后1M
- 特点2:先进后出
- 堆
- 存储引用类型的实际数据
- 特点:空间比较大,存储速度慢
- 栈
public static void main(String[] args) {
// 1.创建变量
int num = 10;
// 2.创建数组
int[] arr = new int[3];
arr[0] = 10;
arr[1] = 8;
arr[2] = 15;
}
public static void main(String[] args) {
int[] arr = new int[3];
int[] arr2 = {100, 200, 300, 400, 500};
arr = arr2;
for (int i : arr) {
System.out.println(i);
}
}
6.数组的扩容
- 创建数组时,必须显示指定长度,并在创建之后不可更改长度。
- 扩容的思想:
- 创建大于原数组长度的新数组。
- 讲原数组中的元素依次复制到新数组中。
6.1 复制的方式
- 循环将原数组中所有元素逐一赋值给新数组。
- 使用for循环实现。
Array.copyOf(原数组, 新长度); // 返回带有原值的新数组。
6.2 地址的替换
- 数组作为引用类型之一,其变量中存储的是数组的地址。
- 完成元素赋值后,需将新数组地址,赋值给原变量进行替换。
7.数组的排序
- 冒泡排序:相邻的两个数值比较大小,互换位置。
- 选择排序:固定值与其他值依次比较大小,互换位置。
- JDK排序:
java.util.Arrays.sort(数组名); // JDK提供(升序)
8.数组的应用
8.1数组类型的参数
public class TestArrayParameter {
public static void main(String[] args) {
int[] nums = {111, 222, 333, 444, 555}; // 假设nums地址为:0x0000A001
printArray(nums);
}
public static void printArray(int[] oneArray) { // 参数传入后oneArray地址为:0x0000A001
for (int i = 0; i < oneArray.length; i++) {
System.out.println(oneArray[i]);
}
}
}
/*
运行结果:
111
222
333
444
555
*/
- 方法调用时,将nums中的地址赋值给oneArray,此时二者指向同一数组。
8.2数组类型的返回值
public class TestReturnValue {
public static void main(String[] args) {
int[] oa = {}; // 假设地址0x0000A111
int[] na = expand(oa);
for (int i = 0; i < na.length; i++) {
System.out.println(na[i]);
}
}
public static int[] expand(int[] oldArray) { // 0x0000A111
int[] newArray = new int[oldArray.length*2]; // 0x0000B222
for (int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
return newArray; // 0x0000B222
}
}
/*
运行结果:
111
222
333
444
555
0
0
0
0
0
*/
- 返回长度为10的newArray
- 创建新数组,长度为原数组的2倍,新数组中保留原有数据,返回新数组。
8.3数组类型的返回值
public class TestArrayParameter {
public static void main(String[] args) {
printArray(111, 222, 333, 444, 555); // 可为可变长参数赋予0 ~ N个实际参数
}
public static void printArray(int... oneArray) { // 定义int型可变长参数
for (int i = 0; i < oneArray.length; i++) {
System.out.println(oneArray[i]);
}
}
}
/*
运行结果:
111
222
333
444
555
*/
- 概念:可接收多个同类型实参,个数不限,使用方式与数组相同。
- 语法:
数据类型... 形参名; // 必须定义在形参列表的最后,且只能有一个。
9.二维数组
9.1 概念
- 概念:一维数组中的一维数组;数组中的元素还是数组。
9.2 二维数组创建语法
// 先声明、再分配空间:
数据类型[][] 数组名;
数组名 = new 数据类型[高维长度][低维长度];
- 声明并分配空间:
// 声明并分配空间:
数据类型[][] 数组名 = new 数据类型[高维长度][低维长度];
- 声明并赋值(繁):
// 声明并赋值(繁):
数据类型[][] 数组名 = new 数据类型[高维长度][]; // 不规则数组,自行new低维数组
- 声明并赋值(简):
// 声明并赋值(简):
数据类型[][] 数组名 = {{v1, v2, v3}, {v4, v5}, {v6, v7, v8, v9}}; // 显示初始化
9.3 二维数组的赋值
public class Test2DArray {
public static void main(String[] args) {
int[][] array = new int[3][5];
array[0][0] = 10;
array[0][3] = 20;
array[1][1] = 30;
array[1][2] = 40;
array[2][4] = 50;
}
}
- 使用双下标访问二维数组中的元素,
- 第一个下标代表,行号(高维下标),
- 第二行下标表示,列号(低维下标)。
9.4 二维数组的内存分配
- 高维数组中的每一个元素,保存了低维数组的地址,访问array[0]等价于在访问0x0000A111
9.5 二维数组的访问
public class Test2DArray {
public static void main(String[] args) {
int[][] array = new int[3][5];
array[0][0] = 10;
array[0][3] = 20;
array[1][1] = 30;
array[1][2] = 40;
array[2][4] = 50;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j]);
}
System.out.println();
}
}
}
- 访问低维长度:array[i].length首个低维数组的长度
- 访问低维数组元素:array[i][j]首个低维数组的首个元素
课堂案例
- 杨辉三角
public class PascalTriangle {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入杨辉三角的行数:");
int n = sc.nextInt();
int[][] nums = new int[n][];
for (int i = 0; i < n; i++) {
// 创建内层数组
nums[i] = new int[i + 1];
// 遍历数组
for (int j = 0; j < nums[i].length; j++) {
if (j == 0 || j == i) {
nums[i][j] = 1;
} else {
nums[i][j] = nums[i - 1][j - 1] + nums[i - 1][j];
}
}
}
for (int i = 0; i < nums.length; i++) {
for (int k = nums.length-i-1; k > 0; k--) {
System.out.print(" ");
}
for (int j : nums[i]) {
System.out.print(j + " ");
}
System.out.println();
}
}
}
总结
- 数组的概念:
一组连续的存储空间,存储多个相同数据类型的值。 - 数组的声明与赋值:
数据类型[] 数组名 = new 数据类型[长度];
数组名[下标] = 值;
- 数组的遍历:
从头至尾,逐一对数组的每个元素进行访问。 - 数组的排序:
冒泡排序、选择排序、JDK快速排序。 - 数组的应用:
数组复制、数组扩容、数组参数、数组返回值、二维数组。
作业
- 定义一个函数,获取某个数组中的最小值
- 定义一个数组,数组成员10个,找出数组中最大数连同下标一起输出
- 给定一个整型数组,数组成员10个,求该数组中第二大的数的下标
- B哥去参加青年歌手大奖赛,有10个评委打分,(去掉一个最高一个最低)求平均分?
- 利用选择排序对数据进行降序排序
- 定义数组,存放5个学生的成绩【成绩值自己设定】,将成绩从大到小排序,获得成绩之和,平均成绩,最小成绩,最大成绩。
- 定义一个长度为10的int数组,统计数组中的最大值、最小值、以及奇数和偶数的个数
- 提取一个方法,将指定数组中的数组元素进行反转
例如:{10,23,2,45,6}—>{6,45,2,23,10} - 将一个数组逆序输出
- 输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组
- 有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中
面试题
- 基本数据类型和引用数据类型之间的区别
- 在Java中,声明一个数组过程中,是如何分配内存的
- 分别使用冒泡和选择对已知数组进行排序