这里写自定义目录标题
第9章 数组
01 练习
- 定义方法,功能是:打印一个4行5列的*矩形,在主方法中调用该方法。
public class Day071 {
public static void f1() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
System.out.print("*");
}
System.out.println();
}
}
public static void main(String[] args) {
f1();
}
}

2.定义方法:功能是打印一个m行n列的“某符号”矩形,在主方法中调用。
public static void f2(int m,int n,char c) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
System.out.print(c);
}
System.out.println();
}
}
public static void main(String[] args) {
f1();
f2(5,6,'.');
}

3.定义方法:计算矩形的面积,长4宽3,在主方法中调用,并在主方法中显示结果。
public static int f3() {
return 4 * 5;
}
public static void main(String[] args) {
System.out.println(f3());
}

4.定义方法:计算矩形的面积,长x宽y,在主方法中调用,并在主方法中显示结果。
public static int f4(int x,int y) {
return x * y;
}
public static void main(String[] args) {
System.out.println(f4(6,5));
}

5.定义方法:找出三个数中的最大值,在主方法中调用,并在主方法中显示结果。
public static int f5(int a,int b,int c) {
int max = Integer.MIN_VALUE;
if(a > max) {
max = a;
}
if(b > max) {
max = b;
}
if(c > max) {
max = c;
}
return max;
}
public static void main(String[] args) {
System.out.println(f5(3,4,5));
}



按住ctrl+鼠标左键,点击,进入该方法源码查看。
02 数组的概念
数组是一个容器,它可以保存一定数量的同一类型的数据。
当数组创建完成后,它的长度就固定下来了。

数组中的每个数据称为元素,每个元素都可以通过索引(index)来访问,
上面数组有10个元素,数组的长度是10,
数组的索引从0开始,如:第9个元素,需要通过索引8来访问。
03 创建、初始化和访问数组
public class Day072 {
public static void main(String[] args) {
//声明了一个数组变量arr
//变量的类型是int[],int是数组中元素的类型
int[] arr;
//使用new操作符创建了一个容纳10个int的数组
arr = new int[10];
arr[0] = 10;// 初始化第一个元素
arr[1] = 20; //初始化第二个元素
arr[2] = 30;
arr[3] = 40;
arr[4] = 12;
arr[5] = 31;
arr[6] = 45;
arr[7] = 5;
arr[8] = 7;
arr[9] = 20;
int a = arr[0]; //取出arr数组的第一个元素,并赋值给a
System.out.println(a);
System.out.println(arr[1]);//将arr数组中第二个元素打印到控制台。
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println(arr[5]);
System.out.println(arr[6]);
System.out.println(arr[7]);
System.out.println(arr[8]);
System.out.println(arr[9]);
System.out.println(arr[10]);//导致运行时的错误,数组索引越界。
}
}

public class Day072 {
public static void main(String[] args) {
//声明了一个数组变量arr
//变量的类型是int[],int是数组中元素的类型
int[] arr;
//使用new操作符创建了一个容纳10个int的数组
arr = new int[10];
arr[0] = 10;// 初始化第一个元素
arr[1] = 20; //初始化第二个元素
arr[2] = 30;
arr[3] = 40;
arr[4] = 12;
arr[5] = 31;
arr[6] = 45;
arr[7] = 5;
arr[8] = 7;
arr[9] = 20;
int a = arr[0]; //取出arr数组的第一个元素,并赋值给a
System.out.println(a);
System.out.println(arr[1]);//将arr数组中第二个元素打印到控制台。
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println(arr[5]);
System.out.println(arr[6]);
System.out.println(arr[7]);
System.out.println(arr[8]);
System.out.println(arr[9]);
//System.out.println(arr[10]);//导致运行时的错误,数组索引越界。
//可以使用其他类型的数组
byte[] arr1 = new byte[5];
short[] arr2 = new short[5];
long[] arr3 = new long[5];
float[] arr4 = new float[5];
double[] arr5 = new double[5];
boolean[] arr6 = new boolean[5];
char[] arr7 = new char[5];
String[] arr8 = new String[5];
//可以使用更加简洁的方式来创建和初始化数组
int[] arr9 = {100,200,300,400,500};
System.out.println(arr9[2]);
System.out.println(arr9.length);//获取数组的长度
System.out.println(arr9[arr9.length - 1]);//取数组的最后一个元素
//动态的创建数据
int n = 10;
int[] arr10 = new int[n];
}
}
_________________________________
10
20
30
40
12
31
45
5
7
20
300
5
500

- 堆,栈(SGT)

为什么要分堆和栈呢?
栈的空间小,速度快;
堆的空间大,速度慢。

tip:
//数组是引用数据类型
//声明了一个数组变量arr
//变量的类型是int[],int是数组中元素的类型
//这个声明不会真正的创建数组,它只是声明了一个可以引用int类型数组的变量
int[] arr;
//使用new操作符创建了一个容纳10个int的数组
//将数组的引用(地址)赋值给变量arr,这样arr就会引用这个数组

04 遍历数组
- 使用for循环遍历数组
public class Day073 {
public static void main(String[] args) {
//使用for循环遍历数组
int[] arr = {100,200,300,400,500,600,700,800,900,1000};
System.out.println(arr.length); //10
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
---------result-----------------
10
100
200
300
400
500
600
700
800
900
1000

- foreach
使用增强的for循环来遍历数组
选中foreach那一行,回车


public class Day073 {
public static void main(String[] args) {
//使用for循环遍历数组
int[] arr = {100,200,300,400,500,600,700,800,900,1000};
System.out.println(arr.length); //10
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
System.out.println("********************************");
//使用增强的 for循环来遍历数组
for (int e : arr) {//代表当有元素,每次循环自动对e进行赋值
System.out.println(e);
}
}
}
--------result--------------
10
100
200
300
400
500
600
700
800
900
1000
********************************
100
200
300
400
500
600
700
800
900
1000

- 使用for循环可以修改数组中元素的值
//使用for循环可以修改数组中元素的值
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
arr[i] = arr[i] - 1;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
-------------result-----------
100
200
300
400
500
600
700
800
900
1000
99
199
299
399
499
599
699
799
899
999

- 使用foreach不能修改元素的值
//使用foreach不能修改元素的值
for (int e : arr) {
e = e - 1;
}
for (int e : arr) {
System.out.println(e);
}
//程序走到此处,按想象应为99-1,199-1,299-1,......
//即98,198,298,......
//但不是的,用foreach,没有修改成功
-------result-------
99
199
299
399
499
599
699
799
899
999

tip: 使用foreach时,数组没有下标(索引)。
05 基本类型和引用类型的区别
- 例一
public class Day074 {
public static void main(String[] args) {
int a = 9;
int b = a; //将a的值拷贝给b
a = 8;
System.out.println(b); //9
}
}
-------Console result---------
9

2. 引用类型的赋值
int[] arr1 = {100,200,300};
int[] arr2 = arr1; //将arr1的引用(地址)赋值给arr2
arr1[0] = 101;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
-----------Console result----------
101
101


3. 基本类型的传参
例3.1:
public class Day075 {
public static void f(int n) {
n = 9;
}
public static void main(String[] args) {
int a = 10;
f(a); //基本类型的传参和赋值是一样的,都是拷贝
System.out.println(a); //10
}
}

例 3.2
public class Day075 {
public static void f(int n) {
n = 9;
}
public static void main(String[] args) {
int n = 10;
f(n); //基本类型的传参和赋值是一样的,都是拷贝
System.out.println(n); //10 这里的n和方法f中的n不是同一个变量
}
}

关注点:
作用域
main方法中和f方法中的n,不是一个n, 是不同的n。
- 引用类型的传参
public class Day076 {
public static void f(int[] n) {
n[0] = 9;
}
public static void main(String[] args) {
int[] a = {100,200,300};
f(a); //将实际参数a的值(数组的地址)拷贝给形式参数n,现在a和n引用同一个数组
System.out.println(a[0]); //9
}
}

- 基本类型的相等比较和引用类型的相等比较
5.1
int a = 10;
int b = 10;
System.out.println(a == b); //true
5.2
int[] arr1 = {1,2,3}; //10001000
int[] arr2 = {1,2,3}; //10001001
System.out.println(arr1 == arr2); //false arr1和arr2存放的是不同的数组的地址
int[] arr3 = arr2;
System.out.println(arr3 == arr2); //true arr1和arr2存放的是同一个数组的地址

06 复制数组
复制方式
- 错误的复制方式
//错误的复制方式
int[] arr1 = { 100, 200, 300 };
int[] arr2 = arr1;
arr1[0] = 101;
System.out.println(arr2[0]); //101

- 正确的复制方式
//复制数组的正确方式
int[] arr1 = {100,200,300};
int[] arr3 = new int[arr1.length];
for (int i = 0; i < arr3.length; i++) {
arr3[i] = arr1[i];
}
arr1[0] = 101;
System.out.println(arr3[0]); //100 arr1和arr3引用的不同的数组

- 使用java类库存来复制数组




//使用java类库存来复制数组
int[] arr1 = {100,200,300};
int[] arr4 = new int[arr1.length];
//src是源数组
//srcPos,从源数组的那个超级赛亚人引开始复制
//dest是目标数组
//destPos是从目标数组的哪个索引开始粘贴
//length是复制多少个元素
//System.arraycopy(src, srcPos, dest, destPos, length);
System.arraycopy(arr1, 0, arr4, 0, arr1.length);
arr1[0] = 101;
//System.out.println(arr4[0]); //100
for (int i : arr4) {
System.out.println(i);
}
-------------Console result-------
100
200
300




int[] arr1 = {100,200,300};
//int[] arr5 = new int[arr1.length];
//original是源数组
//newL
//Arrays.copyOf(original, newLength)
int[] arr5 = Arrays.copyOf(arr1, 2);//创建一个长度为newLength新的数组,并返回
for (int i : arr5) {
System.out.println(i);
}
System.out.println(arr5.length); //2
------------Console result--------------
100
200
2

07 Array类和二维数组
使用Arrays类
7.1


public static void main(String[] args) {
int[] arr1 = {1,2,3};
int[] arr2 = {1,2,3};
int[] arr3 = {2,2,3};
System.out.println(arr1 == arr2); //false
System.out.println(Arrays.equals(arr1, arr2)); //true 比较元素的值(不是比较地址)
System.out.println(Arrays.equals(arr1, arr3)); //false 比较元素的值
----------Console result----------
false
true
false

7.2 填充
//填充
int[] arr = new int[3];
for (int i : arr) {
System.out.println(i);//int数组中的元素默认值是0
}
Arrays.fill(arr, 2); //使用2填充arr数组的每个元素
for (int i : arr) {
System.out.println(i);
}
-----------Console result---------
0
0
0
2
2
2

7.3 排序
//排序
int[] arr = {20,4,15,80};
Arrays.sort(arr);//从小到大排序
for (int i : arr) {
System.out.println(i);
}

7.4 查找
//查找
int[] arr = {20,4,15,80};
System.out.println(Arrays.binarySearch(arr, 15));//2


7.5 格式化输出
//格式化输出
int[] arr = {20,4,15,80};
System.out.println(arr); //[I@1db9742
System.out.println(Arrays.toString(arr)); //[20, 4, 15, 80]





二维数组
二维数组是数组的数组。数组中的每个元素都是数组。

7.6 使用for遍历数组
public class Day0710 {
public static void main(String[] args) {
//创建了一个二维数组
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[] a1 = arr[0];
int[] a2 = arr[1];
int[] a3 = arr[2];
System.out.println(arr[0][0]); //取1
System.out.println(arr[0][1]); //取2
System.out.println(arr[0][2]); //取3
System.out.println(arr[1][0]); //取4
System.out.println(arr[1][1]); //取5
System.out.println(arr[1][2]); //取6
System.out.println(arr[2][0]); //取7
System.out.println(arr[2][1]); //取8
System.out.println(arr[2][2]); //取9
System.out.println("********************");
System.out.println(arr.length);//数组长度为3
System.out.println("\n");
//使用foreach遍历数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}

例2: 如果去掉某几个元素

tips:
int[][] arr = {{1,2,3},1,{7,8,9}}; //编译错误,每个元素都必须是数组
例3: foreach来遍历数组


//foreach来遍历数组
for (int[] a : arr) {
for (int i : a) {
System.out.print(i);
}
System.out.println();
}

7.7 打印二维数组
例1:
//打印二维数组
System.out.println(arr);//输出地址 [[I@1db9742 两个中括号代表是二维数组
System.out.println(Arrays.toString(arr)); //[[I@106d69c, [I@52e922, [I@25154f]
System.out.println(Arrays.deepToString(arr)); //[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
//打印二维数组
System.out.println(arr);//输出地址 [[I@1db9742 两个中括号代表是二维数组
System.out.println(Arrays.toString(arr)); //[[I@106d69c, [I@52e922, [I@25154f]
System.out.println(Arrays.deepToString(arr)); //[[1, 2, 3], [4, 5, 6], [7, 8, 9]]


例2:
//打印二维数组
System.out.println(arr);//输出地址 [[I@1db9742 两个中括号代表是二维数组
System.out.println(Arrays.toString(arr)); //[[I@106d69c, [I@52e922, [I@25154f]
System.out.println(Arrays.deepToString(arr)); //[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for (int[] a : arr) {
System.out.println(Arrays.toString(a));
}
//打印二维数组
System.out.println(arr);//输出地址 [[I@1db9742 两个中括号代表是二维数组
System.out.println(Arrays.toString(arr)); //[[I@106d69c, [I@52e922, [I@25154f]
System.out.println(Arrays.deepToString(arr)); //[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for (int[] a : arr) {
System.out.println(Arrays.toString(a));
}
----------Console result--------------
[[I@1db9742
[[I@106d69c, [I@52e922, [I@25154f]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]


练习
- 写一个方法,返回数组中元素的最大值。
- 写一个方法,返回数组中所有元素的和。
- 写一个方法,接受一个数组参数,返回反转的数组。
- 写一个方法,输出数组中元素的最大值和索引。
数组操作与应用
本文深入讲解数组的概念,包括数组的创建、初始化、访问和遍历方法。探讨了基本类型与引用类型的区别,复制数组的不同方式,以及使用Array类和二维数组的高级技巧。通过实例演示了如何计算矩形面积、找出最大值、遍历和复制数组,以及在数组中查找和排序元素。
1765

被折叠的 条评论
为什么被折叠?



