数组的定义及操作、递归

数组

概念:数组是存储同一种数据类型多个元素的集合。也可以看成是一个容器。

数组既可以存储基本数据类型,也可以存储引用数据类型

一维数组

定义格式:

1
2
3
格式一:数据类型[] 数组名;

格式二:数据类型 数组名[];

举例:

1
2
3
int[ ] a; //定义了一个int类型的数组a;

int a[ ]; //定义了一个int类型的数组a;

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ArrayDemo {
public static void main(String[] args) {
//数组:你可以一个容器,他用来存储一组相同类型的数据。
//数组的定义语法
//方式1:动态的定义方式,由我们规定数组的长度,由系统赋默认值
//创建一个int类型的数组
//当我们创建好了数组后,系统会给分配索引(角标)从0开始
int[] arr=new int[10];
//往数组中放入数据 通过数组的索引往里面存数据
arr[0]=10;
arr[1]=20;
arr[2]=30;
//取数组中的元素
int num=arr[2];
System.out.println(num);
System.out.println(arr[4]);
System.out.println(arr[5]);

//语法2
boolean bs[]=new boolean[2];
bs[0]=true;
System.out.println(bs[0]);
System.out.println(bs[1]);

}
}

数组可以存储基本数据类型,也可以存储引用数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ArrayDemo {
public static void main(String[] args) {
int[] arr1 = new int[3];
arr1[0] = 10;
arr1[1] = 20;
System.out.println(arr1[1]);

int[] arr2 = new int[3];
arr2[0] = 100;
arr2[1] = 200;
System.out.println(arr2[1]);

System.out.println(arr1);
System.out.println(arr2);

//数据类型:基本数据类型和引用数据类型
//引用数据类型,你使用new关键字初始化的数据 数组 类 接口 枚举

Java中的内存分配以及栈和堆的区别

  • 栈: 存放的是局部变量

    局部变量:在方法定义中或者方法声明上的变量都是局部变量。

  • 堆: 存放的是所有new出来的东西

  • 特点:

    a: 每一个new出来的东西都会为其分配一个地制值。
      b: 每一个变量都有一个默认的值
    
1
2
3
4
5
byte,short,int,long -------->0
float,double ---------------------->0.0
char –---------------------------------->‘\u0000’
boolean ------------------------------> false
引用数据类型------------------------> null

使用完毕就变成了垃圾,等待垃圾回收器对其回收

  • 方法区
  • 本地方法区:(和系统相关)
  • 寄存器:(cpu使用)

两个数组的内存图

两个数组的内存图

三个数组的内存图

三个数组的内存图

1
2
3
4
5
执行流程:
定义第一个数组,定义完毕后,给数组元素赋值。赋值完毕后,再输出数组名称和元素
定义第二个数组,定义完毕后,给数组元素赋值。赋值完毕后,再输出数组名称和元素
定义第三个数组,把第一个数组的地址值赋值给它。(注意类型一致),通过第三个数组的名称去把元素重新赋值
最后,再次输出第一个数组数组名称和元素

数组的初始化

Java中数组必须先初始化才能使用,即为数组中的元素分配内存空间并赋值

初始化的分类:

​ (1)动态初始化: 只指定长度,由系统给出初始化值

​ (2)静态初始化: 给出初始化值,由系统决定长度

​ 注意:两种初始化方式只能使用一种,不能动静结合

动态初始化

格式:

1
数据类型[] 数组名 = new 数据类型[数组长度];

举例:

1
int[] arr = new int[3]; //定义了一个int类型的数组arr,这个数组可以存放4个int类型的值。

动态初始化的内存图解

动态初始化数组的内存图

静态初始化

格式:

1
数据类型[] 数组名 = new 数据类型[]{元素1,元素2,…};

举例: i

1
int[] arr = new int[]{1,2,3};

简化格式:

1
数据类型[] 数组名 = {元素1,元素2,…};

举例:

1
int[] arr = {1,2,3};

静态初始化内存图

数组的静态初始化的内存图解

1
2
3
4
5
6
7
8
9
10
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4 }; // 静态初始化
// 下面的代码是依次访问数组中的元素
System.out.println("arr[0] = " + arr[0]);
System.out.println("arr[1] = " + arr[1]);
System.out.println("arr[2] = " + arr[2]);
System.out.println("arr[3] = " + arr[3]);
}
}

一维数组常用操作

数组的遍历

1
2
3
4
5
6
7
public static void main(String[] args) {
int[] arr={10,20,50,40,102};
//数组的遍历
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}

数组获取最值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static void main(String[] args) {
//获取数组中的最大值或最小值
int[] arr = {10, 20, 50, 40, 102};
int max = getMax(arr);
System.out.println("最大值是" + max);
}

public static int getMax(int[] arr){
int max = arr[0];
for(int i = 1; i<arr.length; i++){
if(arr[i]>arr[0]){
max = arr[i];
}
}
return max;
}

数组反转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class ArrayDemo3 {
public static void main(String[] args) {
//数组元素反转(就是把元素对调)
int[] arr = {10, 20, 30, 40, 50}; //50 40 30 20 10

for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}

reverseArray(arr);
showArray(arr);


}

//数组元素反转
private static void reverseArray(int[] arr) {
//分析:首尾元素值交换,遍历一半
for (int i = 0; i < arr.length / 2; i++) {
//采用中间变量进行值交换
int t = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = t;

}
}
//遍历数组
private static void showArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}


}

数组查表法

根据键盘录入索引,查找对应星期

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.Scanner;
public class ArrayDemo8 {
public static void main(String[] args) {
//数组查表法(根据键盘录入索引, 查找对应星期)
//根据索引查元素
String[] arr = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数 1----7");
int index = scanner.nextInt();
String str = getElementByArray(index, arr);
System.out.println(str);
}

private static String getElementByArray(int index, String[] arr) {
if (index >= 1 && index <= 7) {
return arr[index - 1];
} else {
return "查无此元素";
}
}
}

数组基本查找

查找指定元素第一次在数组中出现的索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
public class ArrayDemo9 {
public static void main(String[] args) {
//根据元素查索引
String[] arr = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个星期");
String str = scanner.nextLine();//获取用户输入的字符串
int index = getIndex(str, arr);
System.out.println("该元素的索引是" + index);
}

private static int getIndex(String str, String[] arr) {
//遍历数组
for (int i = 0; i < arr.length; i++) {
if (str.equals(arr[i])) {
return i;
}
}
return -1; // 一般喜欢用 -1 代表没找到
}
}

数组操作的两个常见小问题越界和空指针

ArrayIndexOutOfBoundsException:数组索引越界异常

每个数组的索引都有一个范围,即0~length-1。在访问数组的元素时,索引不能超出这个范围,否则程序会报错,如下所示。

1
2
3
4
5
6
public class ArrayDemo06 {
public static void main(String[] args) {
int[] arr = new int[4]; // 定义一个长度为4的数组
System.out.println("arr[0]=" + arr[4]); // 通过角标4访问数组元素
}
}

出现这个异常的原因是数组的长度为4,其索引范围为0~3,而上述代码中的第4行代码使用索引4来访问元素时超出了数组的索引范围。

NullPointerException:空指针异常

在使用变量引用一个数组时,变量必须指向一个有效的数组对象,如果该变量的值为null,则意味着没有指向任何数组,此时通过该变量访问数组的元素会出现空指针异常

1
2
3
4
5
6
7
8
9
public class ArrayDemo2 {
public static void main(String[] args) {
int[] arr = new int[]{10, 20};
arr = null;// 人为置空
//NullPointerException 空指针异常
int length = arr.length;
System.out.println(length);
}
}

二维数组

概念:二维数组其实就是每一个元素为一维数组的数组

定义格式:

数据类型[][] 变量名 = new 数据类型[m][n]

m表示这个二维数组有多少个一维数组 必须写上
n表示每一个一维数组的元素个数 可不写

举例:

int[][] arr = new int[3][2];

表示定义了一个二维数组arr,这个二维数组有3个一维数组,名称是arr[0],arr[1],arr[2],每个一维数组有2个元素,可以通过arr[m][n]来获取

注意事项:

(1)以下格式也可以表示二维数组:

数据类型 数组名[] [] = new 数据类型[m] [n];

数据类型[] 数组名[] = new 数据类型[m] [n];

(2)int[] x,y[]; //定义了两个数组 一个是一维数组x= new int[3],另一个是二维数组y=new int[3] []

二维数组的内存图

二维数组的内存图

二维数组常用操作

二维数组遍历

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {
int[][] arr = {{2, 4}, {10, 30}, {10, 30, 40}, {10, 1}};
//二维数组的遍历
for (int i = 0; i < arr.length; i++) {
//System.out.println(arr[i]); //一维数组
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
}

打印杨辉三角

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class ArrayDemo {
public static void main(String[] args) {
//B:
//需求:打印杨辉三角形(行数可以键盘录入)
//
//1
//1 1
//1 2 1
//1 3 3 1
//1 4 6 4 1
//1 5 10 10 5 1
//
/**
* 分析规律:
* 1.每一行的第一个数和最后一个数都是1
* 2.从第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数");
int n = sc.nextInt();
//1.第一个数和最后一个数都是1
//2.第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
int[][] arr=new int[n][n]; //定义一个数组,行列数都一样
for (int i = 0; i < arr.length; i++) {
arr[i][0]=1; //将每一行的第一个数,置成1
arr[i][i]=1; //将三角形的每一行的最后一个元素置成1
}
//计算中间元素
for (int i =2; i < arr.length; i++) {
for (int j =1; j <= i-1; j++) {
//第三行开始,中间的数等于我上一行的前一列的数和我上一行本列的数之和
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
}
//遍历二维数组
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <=i; j++) {
System.out.print(arr[i][j]+"\t");
}
System.out.println();
}

}
}

递归

递归概述: 方法定义中调用方法本身的现象
递归注意事项:

  • ​ 要有出口,否则就是死递归
  • ​ 次数不能太多,否则就内存溢出

斐波那契数列

案例:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问第二十个月的兔子对数为多少?
由此可见兔子对象的数据是:1 , 1 , 2 , 3 , 5 , 8 …

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyTest2 {
public static void main(String[] args) {
// 1 1 2 3 5 8 13 21 从第三个数开始,这个数等于前两个数之和 (斐波那契数列)
//递归来做
int sum = sumRabbit(20);
System.out.println("兔子的对数" + sum);
}

private static int sumRabbit(int i) {
if (i == 1 || i == 2) {
return 1;
} else {
return sumRabbit(i - 1) + sumRabbit(i - 2);
}
}
}

根据索引查元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ArrayDemo8 {
public static void main(String[] args) {
//A:
//案例演示:
//数组查表法(根据键盘录入索引, 查找对应星期)
//根据索引查元素
//获取跟打印输出是两个概念
String[] arr = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数 1----7");
int index = scanner.nextInt();
String str = getElementByArray(index, arr);
System.out.println(str);
}

private static String getElementByArray(int index, String[] arr) {
if (index >= 1 && index <= 7) {
return arr[index - 1];
} else {
return "查无此元素";
}
}
}

根据元素查索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ArrayDemo9 {
public static void main(String[] args) {
//ctrl+alt+O 优化导包,没有的包导进来,没有用到的包删掉
//根据元素查索引
String[] arr = {"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个星期");
String str = scanner.nextLine();//获取用户输入的字符串
int index = getIndex(str, arr);

System.out.println("该元素的索引是" + index);

}

private static int getIndex(String str, String[] arr) {
//遍历数组

for (int i = 0; i < arr.length; i++) {
if (str.equals(arr[i])) {
return i;
}

}
return -1; // 一般喜欢用 -1 代表没找到
}
}

在数组中查元素索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test {
public static void main(String[] args) {
int[] arr=new int[]{11,32,55,47,55,79,23};

int num = 55;
int index = getIndex(num,arr);

System.out.println(index);
}
private static int getIndex(int num,int[] arr){
for (int i=0;i<arr.length;i++){
if(num==arr[i]){
return i;
}
}
return -1;
}
}
-------------本文结束感谢您的阅读-------------
0%