作用
:数组
是多个相同类型数据的组合,实现对这些数据的统一管理类型
:数组
也是一种数据类型,它属于引用类型
定义数组:
数组的使用可以分为两种状态分别是静态
、动态
:
静态
:明确知道数组里需要填充的具体元素,如:商品价格、身高、体重等
动态
:不知道数据里需要填充的具体元素是什么,如:1 ~ 100
的阶乘、运算的结果、用户输入 等
静态初始化和动态初始化的语法有些许差别:
静态初始化:数据类型
数组名称
[]
(注:这里的 []
也可以放在 数据类型的后面) =
{ 需要存储的元素,元素与元素之间使用 , 分隔 };
动态初始化:数据类型
数组名称
[]
(注:这里的 []
也可以放在 数据类型的后面) =
new
数据类型
[ 该数组的最大元素储存个数 ];
静态初始化: int array [] = {1, 2, 5, 7, 8};
动态初始化:
int array [] = new int [5];
声明变量 与 创建数组 在同一条语句上完成
int array []; // 声明 array 是 数组类型 array = new int [5]; // 再新建数组对象,并将创建的数组对象赋给变量 array
在使用数组前,我们需要先了解索引
也称index
也有叫 下标
的都是一个意思
我们在上面创建了数组对象, Java
就会为我们在内存中开辟出我们指定的空间,作为 数组 的存储区域,而数组中的每一个储存块都有一个标记号,也就是索引,以上面的例子int array [] = new int [5];
用图片可以这样理解:
在计算机中,记数是以 0 为起始值的,所以这里第1个元素对应的索引就是 0 ...... 第 5 个元素对应的索引就是 4
明白了索引接下来就可以操作数组了
在 Java
中 数组的操作是通过索引来完成的
使用数据名 + 索引值,就可以精确定位到数组的某一个位置,再完成增删改查。
语法:数组名[索引]
例如我们现在给 array
数组第一个元素赋值 (注: 在数组中我们要存储的值统称为元素)
int array [] = new int [5]; // 赋值 array[0] = 168; // 现在 array 第一个元素就是 168 了 // 取值 System.out.println(array[0]); // 打印结果为 168
// 动态初始化 double array [] = new double[10]; // 动态填充 for (int item = 1; item <= array.length; item++) { // 将 item * 1.5 的结果 按顺序填充到 array 数组里 array[item - 1] = item * 1.5; } // 循环遍历, 查看所有结果 for (int index = 0; index < array.length; index++) { System.out.println(array[index]); }
此时 array
数组 用图形表示:
至于后面没有使用到的为什么是 0
后面再一起说
// 静态初始化 byte array [] = {125, 113, 123, 1, 1}; // 循环遍历 for (int index = 0; index < array.lenght; index++) { System.out.println(array[index]); }
此时 array
数组 用图形表示:
数组里的元素能被无限次取用
如果数组创建后没有赋值,那么 Java
会给它设定一个默认值,不同数据类型的默认值不同
byte
/short
/int
/long
整型:默认值 0
float
/double
浮点型:默认值 0.0
char
字符类型:默认值\u0000
boolean
布尔类型:默认值 flase
String
字符串类型:默认值 null
声明数组类型
=> 开辟空间
=> 给数组元素赋值
=> 使用数组
基本类型
、引用类型
,但不能混用。0
为起始值。先看下面这段代码:
// 整数 int num1 = 123; int num2 = num1; num2 = 666; // 数组 int array1 [] = {12, 123, 124}; int array2 [] = array1; array2[0] = 1; // 查看结果 System.out.println("num1 = " + num1); System.out.println("num2 = " + num2); System.out.println("array1[0] = " + array1); System.out.println("array2[0] = " + array2);
以上代码结果为:
num1 = 123 num2 = 666 array1[0] = 1 array2[0] = 1
看完上面的代码你会发现改变 num2
的值并不会影响 num1
的值,而改变了 array2[0]
的值 array1[0]
的值也会跟着变,这种情况与赋值机制有关。
赋值机制分两种情况:
基本类型
:基本类型在进行赋值时是直接在栈
里开辟空间储存要赋的值
引用类型
:引用类型在赋值的时候是在 栈
里开辟空间存放 要赋的引用类型的 内存地址
如图:
所以引用类型
变量记录的是内存地址,修改值是直接到该内存地址里改的,这个地址时共享的,只要有其他变量也指向这个地址,那么只要这个地址里的任意一个值被任意一个指向了这个地址的变量修改了,其他变量读取到的也会时修改后的值。
而 基本类型
变量记录的时值,且将 变量a
赋给 变量b
的时候,变量b
会直接在栈空间中创建一个新的空间,并拷贝 变量a
指向的值存储到这个新空间,此时变量a
和 变量b
之间是相互独立的,它们之间谁改变了都不会影响另一个变量指向的值。
翻转即将数组 {7, 6, 8, 2, 3}
变成 {3, 2, 8, 6, 7}
有两种方法
// 前后对调 /* 即 将 7, 6, 8, 2, 3 中的 首位和最后一位对调 变成 3, 6, 8, 2, 7 再将 第二位 和 倒数第二位对调...以此类推 */ int array [] = {7, 6, 8, 2, 3}; int len = array.length - 1; int temp // 循环 for (int index = 0; index < array.length / 2; index++) { // 因为一次对调两个值, 所以只需要 列表的长度 / 2 次就够了 // 定义临时变量储存 该数组的值 temp = array[index]; /* 因为 index - 1 需要重复用到,且不会有变化 直接把 index - 1 放到循环体外 array[index] = array[(array.length - 1) - index]; 这样写会每次循环都会重复计算 array.length - 1 这是没有必要的消耗 */ // 将 数组[当前索引] 的值 替换为 数组[(数组长度-1) - 当前索引值]的值 array[index] = array[len - index]; // 将 数组[(数组长度-1) - 当前索引值]的值 替换为临时变量储存的值 array[len - index] = temp; } // 打印验证结果是否正确 System.out.print("[ "); for (int x = 0; x < array.length; x++) { System.out.print(array[x] + ", "); } System.out.println("]");
另外一种方法
// 倒序插入法 // 新建一个数组, 倒序读取原数组,插入新数组 int array [] = {7, 6, 8, 2, 3}; // 读取数组最大索引值 int arrayMaxIndex = array.length - 1; // 新建数组 int newArray [] = new int[arrayMaxIndex + 1]; // 以 array 的最大索引值作为循环初始化变量,每次循环 -1 直到 小于 0 停止 for (int index = arrayMaxIndex; index >= 0; index--) { // 用 array 的最大索引值减去当前索引就能得到与当前循环相反的索引值 newArray[arrayMaxIndex - index] = array[index]; } // 最后将 新数组 newArray 赋给 array array = newArray; // 打印验证结果 System.out.print("[ "); for (int x = 0; x < array.length; x++) { System.out.print(array[x] + ", "); } System.out.println("]");
这种方法就是新建一个数组空间,按需求拷贝数组的值,然后把原来的 数组变量指向新的数组空间;
原来的数组空间会被 Java
的内存回收机制销毁
// 数组增加数据 // 现有数组 ['a', 'b', 'c', 'd'] 在其后面添加 'e' 'f' 'g' char charArray[] = {'a', 'b', 'c', 'd'}; // 要插入的数据 char insertData[] = {'e', 'f', 'g'}; // 记录当前数组的元素数量 int currentArrayCount = charArray.length; // 统计要插入的元素数量 int insertItemCount = insertData.length; // 创建新数组 char tempArray[] = new char[currentArrayCount + insertItemCount]; // 新数组的容量使用 当前数组容量 + 要添加元素的数量 // 先拷贝原数组的值 for (int index = 0; index < charArray.length; index++) { tempArray[index] = charArray[index]; } // 添加新元素 for (int index = 0; index < insertData.length; index++) { tempArray[currentArrayCount + index] = insertData[index]; } // 将原数组变量指向新数组 charArray = tempArray; // 打印验证结果 System.out.print("[ "); for (int index = 0; index < tempArray.length; index++) { System.out.print(tempArray[index] + ", "); } System.out.println("]");
数组的每一次扩容都需要创建新的数组, 拷贝原数组的元素, 再添加新元素。
// 数组的删除操作 删除 数值 8 int numArray[] = {5, 6, 7, 8, 9}; // 新建数组 int newArray[] = new int[numArray.length - 1]; // 新数组指针 int newArrayIndex = 0; for (int index = 0; index < numArray.length; index++) { switch (numArray[index]) { // 如果是要删除的值,则不做任何操作 case 8: break; default: // 将 numArray 中的元素拷贝到 newArray 数组中 newArray[newArrayIndex] = numArray[index]; // 拷贝成功后给 newArray 指针 +1 newArrayIndex++; } }
int array[] = {1, 2, 5}; int array[2] = 3; // 对就这么简单,如果需要改多个值,按需求 加个 for 循环就行了
int array[] = {1, 3, 5, 7, 9}; for (int index = 0; index < array.length; index++) { System.out.print(array[index] + "\t"); } System.out.println();