本章目录
一维数组的定义
数组:存储同一种数据类型多个元素的集合。既可以存储基本数据类型,也可以存储引用数据类型。
一维数组的定义格式:
格式一:数据类型[] 数组名; 例如:int[] arr;
格式二:数据类型 数组名[]; 例如:int arr[];
推荐使用第一种定义格式。
一维数组的初始化
数组的初始化就是为数组中的元素分配内存空间,并为每个元素赋值。只有经过了初始化,数组才能使用。
1、数组初始化的分类:
静态初始化:给出初始化值,由系统决定数组的长度。
动态初始化:给出数组长度,由系统初始化元素的值。
2、初始化的格式:
静态初始化:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,……}; 例如:int[] arr = new int[]{1,2,3};
简写:数据类型[] 数组名 = {元素1,元素2,…}; 例如:int[] arr = {1,2,3};
动态初始化:数据类型[] 数组名 = new 数据类型[数组长度]; 例如:int[] arr = new int[3];
数组的长度就是数组中元素的个数。
一维数组图解
一维数组间地址的赋值图解
定义三个数组,将第一个数组的地址赋给第三个数组,改变第三个数组中的元素后,输出一 三数组中的元素,发现第一数组中的元素也发生了变化。
这是因为,第三数组指向了第一数组的地址,改变第三数组中的元素,实际上是对第一数组中的元素进行了改变。
一维数组中常见的操作
1、遍历
public class ArrayDemo02 {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
new ArrayDemo02().print(arr);
}
public void print(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
2、获取最值
public class ArrayDemo03 {
public static void main(String[] args) {
int[] ints = new int[]{15,45,-78,213,-98,156};
System.out.println(new ArrayDemo03().getMax(ints));
System.out.println(new ArrayDemo03().getMin(ints));
}
//获取数组中的最大值
public int getMax(int[] arr) {
int tump = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > tump) {
tump = arr[i];
}
}
return tump;
}
//获取数组中的最小值
public int getMin(int[] arr) {
int tump = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < tump) {
tump = arr[i];
}
}
return tump;
}
}
3、反转
public class ArrayDemo04 {
public static void main(String[] args) {
int[] ints = {1, 2, 3, 4, 5};
int[] reverse = new ArrayDemo04().getReverse(ints);
System.out.println(Arrays.toString(reverse));
}
public int[] getReverse(int[] arr){
int[] ints = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ints[i] = arr[arr.length-1-i];
}
return ints;
}
}
4、查找指定元素第一次在数组中出现的索引
public class ArrayDemo05 {
public static void main(String[] args) {
int[] ints = {1, 2, 3, 4, 3, 8, 6, 4, 8};
System.out.println("结果是:"+new ArrayDemo05().getIndex(ints, 4));
}
public String getIndex(int[] ints, int a) {
for (int i = 0; i < ints.length; i++) {
if (ints[i] == a) {
return String.valueOf(i);
}
}
return "数组中没有所查元素!";
}
}
Java 中栈和堆的区别
栈:存放局部变量,局部变量:在方法定义中或方法声明上的变量。
堆:存放创建的对象。
堆的特点:
每一个创建出来的对象,系统都会为它分配一个地址值。
每一个变量都有初始化值,byte、short、int、long 的默认值为 0;float、double 的默认值为 0.0;char 的默认值为 ‘ ’(\u0000);boolean 的默认值是 false;引用数据类型的默认值是 null。
对象使用完毕后就成了垃圾,等待被回收。
数组操作常见的两个错误
ArrayIndexOutOfBoundsException:数组索引越界异常,原因是访问了不存在的索引。
NullPointerException:空指针异常,原因是数组已不再指向堆内存,我们还用数组访问元素。
二维数组的定义
二维数组:每个元素都是一维数组的数组。
二维数组的定义格式:
格式一:
数据类型[][] 数组名 = new 数据类型[m][n];
格式一有两种变型,但不推荐使用:
数据类型 数组名[][] = new 数据类型[m][n];
数据类型[] 数组名[] = new 数据类型[m][n];
说明:m 表示这个二维数组有多少个一维数组,必须给出;n 表示每个一维数组中元素的个数,可以省略。
例如:int[][] arr = new int[3][2],表示:定义了一个二维数组,这个二维数组中有三个一维数组,分别是:arr[0]、arr[1]、arr[2];每个一维数组中都有两个元素,可以通过 arr[m][n] 来获取。
格式二:
数据类型[][] 数组名 = new 数据类型[m][];
说明:m 表示这个二维数组中有多少个一维数组,没有给出每个一维数组中元素的个数,可以动态给出。
例如:int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
表示:定义一个二维数组,这个二维数组中有三个一维数组,分别是:arr[0]、arr[1]、arr[2];arr[0] 中有两个元素、arr[1] 中有三个元素、arr[2] 中有一个元素。
格式三
数据类型[][] 数组名 = new 数据类型[m][n]{{元素1,…},{元素1,元素2,…},{元素1,元素2,元素3,…},…};
简写:数据类型[][] 数组名 = {{元素1,…},{元素1,元素2,…},{元素1,元素2,元素3,…},…};
例如:int[][] arr = new int[3][2]{{1,2},{1,2},{1,2}};
int[][] arr = {{1,2},{1,2},{1,2}};
二维数组图解
格式一图解:
格式二图解:
格式三图解:
二维数组的遍历
public class ArrayDemo06 {
public static void main(String[] args) {
int[][] ints = {{1, 2}, {3,4}, {5, 6}};
new ArrayDemo06().print(ints);
}
public void print(int[][] ints){
for (int i = 0; i < ints.length; i++) {
for (int j = 0; j < ints[i].length; j++) {
System.out.println(ints[i][j]);
}
}
}
}
杨辉三角
打印杨辉三角形,行数键盘录入
需求:打印杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
public class ArrayDemo07 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入杨辉三角行数:");
int a = scanner.nextInt();
int[][] print = new ArrayDemo07().print(a);
for (int[] ints1 : print) {
for (int i : ints1) {
System.out.print(i+"\t");
}
System.out.println();
}
}
public int[][] print(int a){
//二维数组的第一列和最后一列都是1
/**
* 杨辉三角的形状是一个三角形,所以创建二维数组时的行列不能相同,相同创建成了正方形
* 所以,创建二维数组时,只给定行数,列数根据需要再进行创建
* 这时,创建的列数为:行数 + 1,因为行从 0 开始记
* 每一行的第一个值为 0
* 每一行的最后一个值为 0
*/
int[][] ints = new int[a][];
for (int i = 0; i < a; i++) {
//列数 = 行数 + 1
ints[i] = new int[i+1];
//每一行的第一个值为 0
ints[i][0] = 1;
//每一行的最后一个值为 0
ints[i][i] = 1;
}
/**
* 从第三行开始,除去每行的第一、最后一个数,其余数的值 = 上面的数 + 左上方的数
* 也就是 本列的上一行数 + 前一列上一行数
* 从第三行开始,直到最后一行都需要对其余的数进行计算
* 从第三行第二个数开始后,直到最后一行的倒数第二个数,都要进行计算
*/
//i = 2,是从第三行
for (int i = 2; i < a; i++) {
// j = 1,是第二个数,ints[i].length-1,是该行的倒数第二个数
for (int j = 1; j < ints[i].length-1; j++) {
ints[i][j] = ints[i-1][j] + ints[i-1][j-1];
}
}
return ints;
}
}
递归(5 的阶乘、斐波那契数列)
程序调用自身的编程技巧叫做递归,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归只需少量的程序就可描述出解题过程所需要的多次重复计算,极大地减少了程序的代码量。
求 5 的阶乘
图解:
public class RecursionDemo01 {
public static void main(String[] args) {
System.out.println(new RecursionDemo01().getRecursion(5));
}
public int getRecursion(int a) {
if (a == 1) {
return 1;
} else {
return a * getRecursion(a - 1);
}
}
}
斐波那契数列
1 , 1 , 2 , 3 , 5 , 8 …求第 40 位的值。
从第3位数开始,本位数是前两位数之和。要计算第多少位的值,那么就需要将位数作为参数传进方法进行计算。
public class RecursionDemo02 {
public static void main(String[] args) {
System.out.println(new RecursionDemo02().getRecursion(40));
}
public int getRecursion(int a) {
if (a == 1 || a == 2) {
return 1;
} else {
return getRecursion(a - 1) + getRecursion(a - 2);
}
}
}
真正要做的事,对神明都不会讲.
各位看官本章结束,我们下篇再见 O(∩_∩)O~
-Czx.