六.数组 |
数组是计算机内存中一块连续的存储空间,用来存储多个相同的数据类型的数据 |
一.数组的使用 |
1.声明一个数组 语法: 数据类型【】 数组名;int【】 arr; 推荐使用,更符合程序员的阅读习惯 数据类型 【】数组名;int 【】arr; 数据类型 数组名【】; int arr【】; 2.定义数组的长度(空间) 数组长度=数组空间 语法: 数组名=new 数据类型【长度】; 长度是一个整数代表数组是几块连续的存储空间 3.数组元素的初始化(给数组元素赋值) a.数组元素:数组将每块 空间中存储的数据 被称为数组的元素 b.数组的下标:数组的每块空间都有一个标号,这个标号被称为数组的下标 c.数组下标的范围:0~数组长度-1 语法: 数组名【下标】=数据; 注意: 数组中存放的数据,必须和数组的数据类型匹配 4.访问数组元素 语法: 数据类型 变量名=数组名【下标】; 也可以直接当做值来使用 System.out.println(数组名【下标】); 数组名【下标】+1; ... 注意:如果用一个变量来接收取出的值,那么该变量的类型必须和数组的数据类型匹配 注意: 在访问数组元素,或放置数组元素时,如果使用的下标超出了范围会出现: java.lang.ArrayIndexOutOfBoundsException: 5 数组下标越界异常 5.数组长度 语法: 数组名.length 6.数组的遍历 ===重点=== 遍历: 访问数组的每一个元素,叫做数组的遍历 遍历是一种管理数组元素的有效手段 7.数组其他的声明 | 定义方式 (1)在声明的同时自定义空间 数据类型【】 数组名=new 数据类型【长度】; (2)显示初始化——在声明并开辟空间的同时,给元素赋值 数据类型【】 数组名=new 数据类型【】{元素1,元素2,元素3......}; 或 数据类型【】 数组名; 数组名=new 数据类型【】{元素1,元素2,元素3......}; 注意:显示初始化时,不要设置长度,因为JVM会根据{ }中元素的个数自动生成长度 (3)静态初始化——显示初始化的简便写法——在声明并开辟空间的同时,给元素赋值 数据类型【】 数组名={元素1,元素2,元素3....}; 静态初始化 声明与赋值不可以分开写 以下为错误写法: 数据类型【】 数组名; 数组名={元素1,元素2,元素3....}; |
二.数组的特性 |
1.数组的默认值 需要掌握 数组在分配空间后,会给每个小空间分配一个默认值,默认情况如下 2.数组间的地址传递 数组名中存储的是数组这块连续空间的首地址(起始地址) 通过数组的首地址和数组的下标,按照数组的寻址算法就可以定位数组中任意一块独立空间 数组的寻址算法:首地址+数组下标*数组类型所占字节 因为数组名中存的是地址,这使得数组之间的赋值 是地址的传递,和基本数据类型之间的赋值有很大不同: a.基本数据类型与基本数据类型之间的赋值 值传递: int a=10; int b=a; b++; System.out.println(a);//10 System.out.println(b);//11 b.数组与数组之间的赋值是地址传递 int[] arr = {1,2,3}; int[] arr2 = arr; arr2[1] = 999; for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); //1 993 3 } System.out.println("+++++++++++++++++++++++"); for(int i=0;i<arr2.length;i++){ System.out.println(arr2[i]); //1 999 3 } |
三.数组的应用 |
1.使用在函数的参数上 当一个函数,需要在调用时传入多个相同类型数据时,我们可以将数组作为参数 public static int avg(int[] arr){ //将一个组中所有人的成绩相加 除以总人数 //数组中存储了所有人的成绩 //只需要遍历数组将所有成绩进行累加即可求出总分 int sum = 0; for(int i=0;i<arr.length;i++){ sum += arr[i]; } int avg = sum/arr.length; return avg; } 注意:数组作为参数时,实参给形参赋值 也是地址传递 2.使用在函数的返回值类型上 当一个函数,需要返回多个相同类型的数据时,我们可以将数组作为返回值类型,给给调用者返回一个数组 //写一个函数 接收一整数数组 并挑出数组中所有的偶数 返回给调用者 public static int[] test(int[] arr){//0~n个偶数 int[] arr2 = new int[arr.length]; int index = 0; //遍历传进来的数组,验证每一个元素是否是偶数 for(int i=0;i<arr.length;i++){ if(arr[i]%2==0){//该元素是偶数 arr2[index] = arr[i]; index++; } } //如果是偶数 就放进另外一个数组中 //将存贮所有偶数的数组返回给调用者 return arr2; } |
四.数组的扩容 |
数组的空间长度一旦确定 就不可以更改 1.数组扩容的步骤 数组扩容需要三步: a.创建一个更大的数组——想要一个更大的房子,需要买一个新房子 b.将老数组中的元素转移到新数组中——把老房子的家具,搬进新家 c.新数组给老数组赋值——新房子地址告诉朋友们,卖掉老房子,为了将老数组所占据的内存释放 2.JDK提供的数组扩容工具 语法: 老数组=java.util.Arrays.copyof(需要扩容的目标数组,新数组的长度); int[] arr = new int[4]; arr[0] = 10; arr[1] = 20; arr[2] = 40; arr[3] = 15; for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } System.out.println("进行了数组的扩容"); //使用JDK提供的工具进行扩容 arr = Arrays.copyOf(arr,arr.length*2); arr[4] = 16; for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } |
五.排序 必须掌握 |
排序就是按照一定的规则 将数据进行排序 升序:将数据从从小到大进行排列 降序:将数据从大到小进行排序 1.冒泡排序 必须会默写 a.规则:每次让相邻两个元素进行比较,较大的元素放置在后面,每轮比较出一个较大值 2.选择排序 必须会默写 a.规则:每次固定一个下标,此后与后续元素进行比较 每次将较小的元素 放置到固定下标 3.JDK提供的数组排序工具 JDK提供的数组排序工具 采用了快速排序,这是一种效率非常高的排序算法 语法: java.util.Arrays.sort(数组名); |
六.可变长参数 非重点 |
可变长参数 是JDK1.5之后推出的一种定义参数的新语法 当一个函数 不确定需要几个相同数据类型的数据时,就可以使用可变长参数 语法: public static 返回值类型 函数名 (数据类型...可变长参数名){ 内部使用可变长参数,将可变长参数视为数组即可 } 实参给形参赋值时:实参的值会被打包成一个数组,而可变长参数也会变为数组类型 被这个数组赋值 例: 如果一个函数声明如下: public static int sum(int...a) 那么该函数可以由以下调用语法来调用: sum(); sum(1); sum(2,3); sum(n个实参); int 【】 arr={1,2,3,4,5}; sum(arr); 注意事项: 1.可变长参数,可以和其他参数并存,但是必须放在参数表最后 2.一个参数表中,只能有一个可变长参数 |
七.二维数组 |
一维数组 相当于一条线,一个下标就能确定一个位置 二维数组 相当于一个表格(面),通过行号和列好来确定一个位置 1.声明二维数组 数据类型【】【】 数组名; 推荐第一种 更符合程序员的阅读习惯 数据类型 【】【】数组名; 数据类型 数组名【】【】; int 【】【】 arr1; int 【】【】arr2; int arr3【】【】; 2.二维数组自定义空间 数组名 = new 数据类型【行数】【列数】; 行数:决定了表格有多少行; 列数:决定了表格有多少列; 3.二维数组元素初始化 数组名【行号】【列号】=数据; 行号与列号都是从0开始标记的 行号的范围:0~行数-1 列号的范围:0~列数-1 4.访问二维数组元素 数据类型 变量名=arr【行号】【列号】; 或直接使用 int a=10+arr【行号】【列号】; System.out.println(arr【行号】【列号】); 注意: 行号和列号在使用时,都不可超出范围,否则会出现 java.lang.ArrayIndexOutOfBoundsException 数组下标的越界 5.二维数组的内存结构 实际上 二维数组是一个一维数组元素中 又存储了一个一维数组 外层一维数组:一个一维数组元素中 那么该数组就是外侧层一维数组 内层一维数组:被外层数组所存储的数组被称为内层一维数组 行号对应外层一维数组的下标 列号对应内层是一维数组的下标 二维数组名中 存储的是 外层一维数组的首地址 二维数组名【行号】 存储的是 每个内层一维数组的首地址 所以 二维数组在进行数据的存放和获取时,需要使用两次寻址算法 第一次:通过外层一维数组的首地址加上行号,确定某个内层的一维数组的位置 第二次:通过内层一维数组的首地址加上列号,确定具体的某个空间 6.二维数组的长度 获取外层数组的长度:二维数组名.length 获取内层数组的长度:二维数组名【行号】.length 7.二维数组的遍历 需要会 先遍历外层一维数组,再编列内层数组 for(int i=0;i<arr.length;i++){//外层一维数组的遍历 for(int j=0;j<arr[i].length;j++){ System.out.print(arr[i][j]+" "); } System.out.println(); } 8.二维数组的特性 二维数组与一维数组的特性一致,有默认值,赋值时也是地址传递。 9.不规则的二维数组的声明与定义 一个不规则表格,每行的列数不一样,相当于一个数组中每个元素存储的一维数组长度不一样 (1)不规则二维数组的声明 数据类型【】【】 数组名; 推荐第一种 更符合程序员的阅读习惯 数据类型 【】【】数组名; 数据类型 数组名【】【】; (2)给不规则二维数组开辟空间 数组名=new 数据类型【行数】【】; (3)给每一行,给外层数组的每一个元素 存储一个一维数组 数组名【行号】=数组; (4)注意: a.使用不规则二维数组,行号与列号也不要超出范围,行号的范围是:0~行数-1 列号的范围:取决于某个具体的内层一维数组 b.不规则二维数组获取长度与遍历的方式与规的一致 10.二维数组其他声明与定义方式 (1)声明与开辟空间同时进行 数据类型【】【】 数组名=new 数据类型【行号】【列号】; 数据类型【】【】 数组名=new 数据类型【行号】【】; (2)显示初始化 a. 数据类型【】【】 数组名=new 数据类型【】【】 {{1,2,3},{1,2,3},{1,2,3}...}; 数据类型【】【】 数组名=new 数据类型【】【】{{1,2},{1,2,3},{1}...}; b. 数据类型【】【】 数组名; 数组名=new 数据类型【】【】 {{1,2,3},{1,2,3},{1,2,3}...}; (3)静态初始化 数据类型【】【】 数组名= {{1,2,3},{1,2,3},{1,2,3}...}; 数据类型【】【】 数组名={{1,2},{1,2,3},{1}...}; 声明和赋值不可以分开写 |