数组概念:
数组就是存储数据长度固定的容器,保证多个数据的数据类型要一致。
数组的特点:
1. 数组本身是引用数据类型,但是里面也能存放基本类型,也能存放引用类型。
2. 数组当中的数据,必须类型统一。
3. 【重点】数组的长度一旦确定,不可以发生改变。
如何创建数组?
初始化:在内存当中为数组开辟空间,并且赋予默认值。
数组的初始化方式:
1. 动态初始化(指定长度)
2. 静态初始化(指定内容)
动态初始化格式:
数据类型[] 数组名称 = new 数据类型[长度];
格式解析:
左侧的数据类型
:也就是数组当中存放的所有数据,全都是统一的什么类型
左侧的 [ ]
中括号:代表这是一个数组。
左侧的数组名称
:就是自定义的标识符。
右侧的new关键字
:代表创建的动作。
右侧的数据类型
:必须和左侧完全一样。
右侧 [ ]
中的长度:也就是数组当中到底能放几个数据的个数。
备注:左侧的写法其实可以有两种。
数据类型[] 数组名称 = ... 【推荐】
数据类型 数组名称[] = ...
// 数据类型[] 数组名称 = new 数据类型[长度];
// 初始化一个数组,用来存放int数据,总共能放3个。
int[] arrayA = new int[3];
// 数组能存放5个double数据
double[] arrayB = new double[5];
// 数组能存放10个字符串
String[] arrayC = new String[10];
静态初始化的标准格式:
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, 元素3, ...};
// 创建一个数组,用来存放若干int数据:5, 12, 24, 3, 36
int[] arrayA = new int[] {5, 12, 24, 3, 36};
// 创建一个数组,用来存放字符串:"Hello", "World", "Java", "Kotlin", "Groovy", "Kotlin", "Scala"
String[] arrayB = new String[] {"Hello", "World", "Java", "Kotlin", "Groovy", "Kotlin", "Scala"};
静态初始化的标准格式、省略格式有两种写法。
标准格式:数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, 元素3, ...};
省略格式:数据类型[] 数组名称 = { 元素1, 元素2, 元素3, ...};
注意事项:
1. 静态初始化虽然没有直接指定长度,但是根据内容也可以推算得到长度。
2. 静态的省略格式,虽然没有new关键字
,但是内存当中仍然还是会开辟空间创建数组的。
3. 动态初始化
、静态初始化
的标准格式,都可以拆分成为两个步骤。
4. 静态初始化的省略格式,不可以拆分成为两个步骤。只能一次性完成。
使用建议:
1. 如果知道数组的固定长度,但是里面的内容还不确定,那么尽量使用动态初始化指定长度。
2. 如果直接知晓了数组具体的元素内容,那么就可以直接使用静态初始化指定内容。
// 用省略格式静态初始化了一个数组,其中存放了具体的内容:10, 20, 30
int[] arrayA = {10, 20, 30};
// 动态初始化
int[] arrayB; // 首先定义一个数组
arrayB = new int[3]; // 然后我再开辟空间、初始化
// 静态初始化的标准格式
int[] arrayC;
arrayC = new int[]{5, 15, 25, 35, 44};
// 静态初始化的省略格式
int[] arrayD;
// arrayD = {10, 20, 30}; // 错误写法!
数组原理内存图:
内存概述:
内存是计算机中的重要原件,临时存放存储区域,作用是运行程序。我们编写程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。
java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
java虚拟机的内存划分:
直接打印数组名称,得到的是一个16进制的“地址值”(今后会学到这是一个地址哈希值)。
int[] array = {10, 20, 30};
System.out.println(array); // [I@75412c2f
访问具体数组元素的格式: 数组名称[索引编号]
索引编号:数组当中的每一个元素都有一个int类型编号,从0开始,一直到“数组长度-1”为止。
int[] array = {10, 20, 30}
// 访问数组元素,赋值交给变量
int num = array[1];
System.out.println(num); // 20
如果希望改变数组元素的内容,格式完全一样。
数组名称[索引编号] = 数据值;
使用动态初始化,创建数组的时候没说具体元素是什么,那么就会有一个默认值:
如果是整数,默认为0;
如果是小数,默认为0.0;
如果是字符,默认为’\u0000’;
如果是布尔,默认为false;
如果是引用类型,默认为null(特殊标记,代表什么数据都没有的意思)。
// 将右侧的数据100,赋值交给左侧的array数组当中的第0号元素
array[0] = 100;
array[1] = 120;
array[2] = 150;
System.out.println(array[0]); // 100
System.out.println(array[1]); // 120
System.out.println(array[2]); // 150
数组的索引编号从0
开始,一直到“数组的长度-1
”为止。
如果访问数组元素的时候,指定的索引编号不存在,将会发生什么情况?
发生ArrayIndexOutOfBoundsException异常
,数组索引越界异常。
产生的原因:索引编号写错了。
解决的方案:把索引编号修改到正确范围之内即可。
int[] array = {10, 20, 30};
System.out.println(array[0]); // 10
System.out.println(array[1]); // 20
System.out.println(array[2]); // 30
System.out.println("========");
// System.out.println(array[3]); // 错误,数组角标越界
如果数组只是进行了定义,没有进行new或者{}的初始化,那么数组不能用。
如果数组只是进行了null赋值,却没有进行初始化,那么使用的时候就会发生NullPointerException空指针异常
。
int[] array = null; // 这叫做赋了一个null值,但是没有数组的初始化。
System.out.println(array[0]); // 报数组角标越界异常。
获取数组的长度的格式:数组名称.length
这将会得到一个int数字,代表数组当中元素的个数。
int[] array = {10, 20, 30, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33, 3, 33, 3, 3, 20, 30, 3, 3, 3, 3, 3, 3, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 3, 2};
int len = array.length;
System.out.println("数组的长度:" + len); // len = 42
遍历:通常是说对一大堆数据一个一个逐一处理。
一般情况下,就是说打印输出。所以数组的遍历,就是将数组当中的每一个元素都打印显示出来。
int[] array = {10, 20, 30, 40, 50, 60};
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
选出数组元素的最大值:
public static void main(String[] args) {
int[] array = {5, 20, 50, 35, 10000, 800, -20};
// 这是一个擂台
int min = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] < min) { // 如果当前数组里面的人,比台上的min更小
min = array[i]; // 台上换人
}
}
System.out.println("最小值:" + min);
}
数组元素反转: 只是顺序颠倒,不是排序。
[10, 20, 15] 反转之后 [15, 20, 10]
不能使用新数组,就用唯一 一个数组。
/*通过for循环可以完成元素反转。
初始化语句:int min = 0, max = array.length - 1
条件判断:min < max
步进语句:min++, max--
循环体:借助第三个变量进行交换。
*/
for (int min = 0, max = array.length - 1; min < max; min++, max--) {
int temp = array[min];
array[min] = array[max];
array[max] = temp;
}
任何数据类型都可以作为方法的参数。
如果是基本类型
作为方法参数,那么传递进去的就是数据值
。
如果是引用类型(例如数组)
作为方法参数,那么传递进去是【地址值】
。
只要地址值相同,那么根本就是同一个数组。
public static void main(String[] args) {
int[] array = {10, 20, 30};
// System.out.println("main方法中数组的地址:" + array);
showArray(array);
}
/*
定义一个方法,用来打印遍历数组的内容。“给我来个数组,我帮你遍历。”
三要素
返回值类型:void
方法名称:showArray
参数列表:int[]
*/
public static void showArray(int[] array) { // 参数接收到的其实是一个地址值
// System.out.println("showArray方法接收到的参数地址是:" + array);
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
任何数据类型都可以作为方法返回值,但是方法最多只能有一个返回值。
其实方法返回的也是一个地址值。
public static void main(String[] args) {
int[] result = calculate(10, 20, 30);
System.out.println(result);
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; // 平均值e
// 来个塑料袋,来一个数组
// int[] array = new int[2];
// array[0] = sum;
// array[1] = avg;
int[] array = {sum, avg};
System.out.println(array);
return array;
}
数组不可改变,从内存上分析:
二维数组: