第一章 数组
1.1 数组的概念
- 数组:是一种容器,可以同时存放多个数据值
1.2 数组的特点
- 数组是一种引用型数据类型
- 数组中的数据,类型必须统一
- 数组的长度在程序运行期间不可改变
1.3 数组的定义格式——初始化
- 数组的初始化:在内存当中创建一个数组,并且向其中赋予一些默认值
- 两种常见的初始化方式:
- ++动态初始化(指定长度):创建数组的时候,直接指定数组当中数据元素的个数++
- ++静态初始化(指定内容):创建数组的时候,不指定数据个数,直接指定具体的数据内容++
- 动态初始化数组的格式:
- ++数据类型[] 数组名称 = new 数据类型[数组长度];++
- 左侧数据类型:也就是数组当中保存的类型,全都是统一的什么类型
- 左侧的中括号:表示我是一个数组
- 左侧数组名称:给数组起一个名字
- 右侧的new:代表创建数组的动作
- 右侧数据类型:必须和左侧数据类型保持一致
- 右侧中括号的长度:也就是数组当中,到底可以保存多少个数据(int数字)
- ++注:右侧数组长度根据储存元素个数,不根据索引值++
- 注:可以拆成两个步骤:
- int[] arrayA;
- arrayA = new int[5];
- 静态初始化数组的基本格式:
- ++数据类型[] 数据名称 = new 数据类型[]{元素1, 元素2, …};++
- 注:虽然静态初始化没有告诉长度,但是根据大括号里的具体元素内容,也可以推算出长度
- 注:可以拆成两个步骤:
- int[] arrayA;
- arrayA = new int[]{1, 3, 4};
- 静态初始化数组的省略格式:
- ++数据类型[] 数据名称 = {元素1, 元素2, …};++
- 注:没有指定长度,仍然自动推算长度
- 注:不可以拆成两个步骤
- 注:动态和静态初始化的++使用建议++:
- 如果++不确定数组当中的具体内容++,用动态初始化,否则用今天初始化
1.4 访问数组元素进行获取(静态初始化)
- 直接打印数组名称,得到的是数组对应的:地址内存哈希值
- 访问数组元素的格式:
- 数组名称[索引值]
- 索引值:就是一个int数字,代表数组当中元素的排列编号
- 注:索引值从0开始,一直到++数组的长度-1++为止
1.4 访问数组元素进行赋值(动态初始化)
- 使用动态初始化数组的时候,其中元素会自动拥有默认值:
- 整数类型:0
- 浮点数类型:0.0
- 字符类型:’\u0000’(\u代表unicode,后面0000代表16进制)
- ++布尔类型:fasle++
- 引用类型:null
- 注:静态初始化也有默认值的过程,只是系统将默认值替换成了大括号里的具体值(过程先等于默认值,再等于大括号里的具体值)
1.5 Java中的内存划分(5个部分)
- 栈(Stack):存放的都是方法中的局部变量,++方法的运行一定要在栈当中++
- 局部变量:方法的参数,或者是方法{}内部的变量
- 作用域:一旦超出作用域,立刻冲栈内存当中消失
- 堆(Heap):++凡是new出来的东西,都在堆当中++
- 堆内存里的东西都有一个地址值:16进制
- 堆内存里面的数据都有默认值,例:
- 整数类型:0
- 浮点数类型:0.0
- 字符类型:’\u0000’(\u代表unicode,后面0000代表16进制)
- ++布尔类型:fasle++
- 引用类型:null
- 方法区(Method Area):储存.class(.java编译后用来运行的字节码文件)相关信息,包含方法信息
- 本地方法栈(Native Method Stack):与操作系统相关
- 寄存器(PC Register):与CPU相关
1.6 一个数组的内存图
1.7 两个数组的内存图(不同地址)
1.8 两个引用(arrayB = arrayA)指向同一个数组的内存图(同地址)
- int[] arrayB = arrayA;
- 注:再次输出arrayA时候值和arrayB一样了,因为两个引用名称是同一个数组
1.9 数组索引越界异常
- 如果访问数组元素的时候,索引编号并不存在,那么将会发生++数组索引越界异常++(ArrayIndexOutOfBoundsException)
- 原因:索引编号写错了
1.10 数组空指针异常
- 注:++所有的引用类型变量,都可以赋值为一个null值++。但是代表里面什么都没有
- 数组必须进行++new++初始化++才能使用其中的元素++
- 如果只是赋值一个null,没有进行new创建
- 将会发生:空指针异常(NullPointerException)
- 原因是:无new
- 例:
int[] arryA; arrayA = new arrayA[2]; arrayA[0] = 15; Sysout.out.println(arrayA[0]); //正确 int[] arryA; Sysout.out.println(arrayA[0]); //直接运行不了 int[] arryA = null; Sysout.out.println(arrayA[0]); //空指针异常
1.11 获取数组的长度
- 如何获取数组长度,格式:
- 数组名称.length
- 这将得到一个int数字,代表数组的长度
- 数组一旦创建,程序运行期间,长度不可改变
- 注:这里数组长度没变,是创建了两个数组,只是数组名称相同
1.12 数组的遍历输出
- 遍历数组:就是对数组当中的每一个元素进行逐一,挨个处理。(默认处理方式就是打印输出)
- 例:(快捷方式:数组名称.fori)
int[] arrayA = {1, 3, 4, 5, 6, 7, 8, 42, 32, 12};] //modeOne Sysout.out.println(arrayA[0]); Sysout.out.println(arrayA[1]); ... //modeTwo for(int i = 0; i < 10; i++){ Sysout.out.println(arrayA[i]); } //modeThree for(int i = 0; i < arrayA.length; i++){ //(快捷方式:数组名称.fori) Sysout.out.println(arrayA[i]); }
1.13 数组练习
- 求出数组中的最值
//modeOne public static void main(String[] args) { int[] arrayA = {1, 4, 33, 32, 222, 53, 2}; int max = arrayA[0]; for (int i = 1; i < arrayA.length; i++) { if(max < arrayA[i]){ max = arrayA[i]; } } System.out.println(max); } //modeTwo public static void main(String[] args) { int[] arrayA = {1, 4, 33, 32, 222, 53, 2}; for (int i = 0; i < arrayA.length - 1; i++) { for(int j = 0; j < arrayA.length - i - 1; j++){ if(arrayA[j] < arrayA[j + 1]){ int temp = arrayA[j]; arrayA[j] = arrayA[j + 1]; arrayA[j + 1] = temp; } } } System.out.println("又大到小排列切最大值是:" + arrayA[0]); for (int i = 0; i < arrayA.length; i++) { System.out.print(" " + arrayA[i]); } }
- 数组元素的反转([1, 3, 4, 5]——>[5, 4, 3, 1])
- 要求不能创建新数组
public static void main(String[] args) { int[] arrayA = {1, 3, 4, 5, 6}; System.out.println("本来:"); for (int i = 0; i < arrayA.length; i++) { System.out.print(" " + arrayA[i]); } System.out.println(); System.out.println("============="); System.out.println("交换方式1:"); for (int i = arrayA.length - 1; i >= 0; i--) { System.out.print(" " + arrayA[i]); } System.out.println(); System.out.println("=============="); for (int min = 0, max = arrayA.length - 1; min < max; min++, max--) { int temp = arrayA[min]; arrayA[min] = arrayA[max]; arrayA[max] = temp; } System.out.println("交换方式2:"); for (int i = 0; i < arrayA.length; i++) { System.out.print(" " + arrayA[i]); } }
- 注:数组元素反转:其实就是++对称位置++的元素交换
- 注:通常遍历数组一个索引值,表示对称位置++两个索引++
- 注:交换两个变量需要借助++中间值temp++
1.14 数组作为方法参数_传递地址
- 数组可以作为方法的参数
- ++当调用方法的时候,向方法的小括号进行传参,传递进去的其实是数组的地址值++
public static void main(String[] args) { int[] arrayA = {1, 3, 4, 5, 6, 89}; printArray(arrayA); System.out.println(); printArray(arrayA); } /* 三要素: 返回值类型:只是进行打印,不需要计算,也没有结果,所以用void 方法名称:printArray 参数列表:必须给我数组,我才能打印元素。int[] arrayA */ public static void printArray(int[] arrayA){ for (int i = 0; i < arrayA.length; i++) { System.out.print(" " + arrayA[i]); } }
1.15 数组作为方法返回值_返回地址
- 一个方法++可以有0,1,多个参数++;但是只能有0,1个返回值,++不能有多个返回值++
- 如果希望一个方法中++产生多个结果数据进行返回++,怎么办?
- ++使用一个数组作为返回值类型即可++
public static void main(String[] args) { int[] result = calculate(3, 5, 6); System.out.println("总和:" + result[0]); System.out.println("评价值:" + result[1]); } public static int[] calculate(int a, int b, int c){ int sum = a + b + c; int avg = sum / 3; /*int[] arrayA = new int[2]; arrayA[0] = sum; arrayA[1] = avg;*/ int[] arrayA = {sum, avg}; return arrayA; }
- 注:任何数据类型都能作为方法的参数类型,或者返回值类型
- 注:++数组作为方法的参数,传递进去的其实是数组的地址值++
- 注:++数组作为方法的返回值,传递进去的其实也是数组的地址值++