数组
数组指一组数据的集合,数组中的
每个数据被称作元素
特点
- 数组是一种
引用数据类型 - 长度确定,定义的时候必须指定数组的
长度。 - 类型确定,定义的时候必须声明数组的
类型。
数组的初始化
分类
- 一维数组
- 多维数组
一维数组
两种常见的初始化方式:
- 动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素个数。
- 静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。
动态初始化
动态初始化:创建一个数组,但是没有初始化数组的元素。这种情况需要显式的指定数组大小。
数据类型[ ] 数组名 = new 数据类型[数组长度];
解析含义: 左侧数据类型:也就是数组当中保存的数据,全都是统一的什么类型 左侧的中括号:代表我是一个数组 左侧数组名称:给数组取一个名字 右侧的new:代表创建数组的动作 右侧数据类型:必须和左边的数据类型保持一致 右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个int数字
public class Demo01Array {public static void main(String[] args) {// 创建一个数组,里面可以存放300个int数据// 格式:数据类型[] 数组名称 = new 数据类型[数组长度];int[] arrayA = new int[300];// 创建一个数组,能存放10个double类型的数据double[] arrayB = new double[10];// 创建一个数组,能存放5个字符串String[] arrayC = new String[5];}}
静态初始化
创建一个数组,并已知数组的内部元素
标准格式:数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };
省略格式:数据类型[] 数组名 = {...};
int[] myArr = {0,1,2};
public class ArrayDemo {public static void main(String[] args) {/** 定义语法1* 数据类型[ ] 数组名 = new 数据类型[size];* 定义语法2* 数据类型[ ] 数组名 = {数据1,数据2,数据3};**/int[] myArr = new int[3];System.out.println(myArr[2]);int[] myArr1 = {100, 200, 300};System.out.println(myArr1[1]);// 数组长度// 最大索引 = 数组长度 - 1System.out.println(myArr.length);System.out.println(myArr1.length);}}
注意事项:
1. 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
2. 静态初始化标准格式可以拆分成为两个步骤。
3. 动态初始化也可以拆分成为两个步骤。
4. 静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。
public class Demo03Array {public static void main(String[] args) {// 省略格式的静态初始化int[] arrayA = { 10, 20, 30 };// 2.静态初始化的标准格式,可以拆分成为两个步骤int[] arrayB;arrayB = new int[] { 11, 21, 31 };// 3.动态初始化也可以拆分成为两个步骤int[] arrayC;arrayC = new int[5];// 4.静态初始化的省略格式,不能拆分成为两个步骤。// int[] arrayD;// arrayD = { 10, 20, 30 };}}
使用建议:
- 如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化
数组的默认初始值
| 数组类型 | 默认初始化 |
|---|---|
| byte short int long | 0 |
| float double | 0.0 |
| char | 一个空字符(空格),即‘\\u0000’ |
| boolean | false |
| 引用数据类型 | null,表示变量不引用任何对象 |
静态初始化其实也有默认值的过程,只不过系统自动马上将默认值替换成为了大括号当中的具体数值
数组的索引
直接打印数组名称,得到的是数组对应的:内存地址哈希值。
访问数组元素的格式:数组名称[索引值]
【注意】
索引值从
0开始,一直到“数组的长度-1”为止 ```java public class Demo01 { public static void main(String[] args) {// 静态初始化的省略格式int[] array = { 10, 20, 30 };System.out.println(array); // [I@6e0be858// 直接打印数组当中的元素System.out.println(array[0]); // 10System.out.println(array[1]); // 20System.out.println(array[2]); // 30System.out.println("=============");// 也可以将数组当中的某一个单个元素,赋值交给变量int num = array[1];System.out.println(num); // 20
}
}
<a name="dHCaB"></a>### 内存概述内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。 <br />Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。**JVM的内存划分**| **区域名称** | **作用** || --- | --- || 方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行,存放的都是方法中的`局部变量` || <br /><br />堆内存 | 存储对象或者数组,凡是`new`出来的东西,都在堆中<br />- 堆内存的东西都有一个地址值:`16进制`<br />- 堆内存里面的数据都有`默认值`<br /> || 方法区 | 存储`.class`相关信息,包含方法的信息 || 本地方法栈 | JVM在使用操作系统功能的时候使用 || 寄存器 | 与`cpu`相关 |<a name="HhbWJ"></a>### 数组在内存中的存储> <a name="WQNTh"></a>#### 一个数组内存图```javapublic class Demo02 {public static void main(String[] args) {int[] arr = new int[3];System.out.println(arr);//[I@6e0be858}}
以上方法执行,输出结果[I@6e0be858,是数组在内存中的地址。new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址。

程序执行流程:
main方法进入方法栈执行- 创建数组,jvm会在堆内存中开辟空间,存储数组
- 数组在内存中会有自己的内存地址,以16进制数表示
- 数组中有3个元素,默认值0
- jvm将数组的内存地址赋值给引用类型变量arr
- 变量arr保存的是数组内存中的地址,而不是一个具体的数值,因此称为饮用数据类型

两个数组内存图
public class Demo02 {public static void main(String[] args) {int[] arr = new int[3];int[] arr2 = new int[2];System.out.println(arr);//[I@6e0be858System.out.println(arr2);//[I@61bbe9ba}}


两个引用指向同一个数组的内存图

获取数组长度
格式:数组名称.length
public class ArrayLength {public static void main(String[] args) {int[] array = {12,23,43,55,6,7,2,3,3,4,6};int len = array.length;System.out.println("array数组的长度是:" + len);}
数组一旦创建,程序运行期间,长度不可改变,意思是
new出来的长度不可改变
public class ArrayLength {public static void main(String[] args) {int[] array = new int[3];System.out.println(array.length); // 3array = new int[5];System.out.println(array.length); // 5}}
以上是变量array被赋值,并不少改变new出来数组长度

数组遍历
public class TestArray03 {public static void main(String[] args) {int[] arr = { 1, 2, 3, 4, 5 }; // 定义数组// 使用for循环遍历数组的元素for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]); // 通过索引访问元素}}}
数组最值
最大值
public class DemoMax {public static void main(String[] args) {int[] array = {1,34,56,68,4,32,3};int max = array[0];//// 比武擂台for (int i = 1; i < array.length; i++) {// 如果当前元素,比max更大,则换人if(array[i]>max){max = array[i];}}// 谁最后最厉害,就能在max当中留下谁的战斗力System.out.println("最大值:"+max);}}
最小值
public class DemoMin {public static void main(String[] args) {int[] array = {1,34,56,68,4,32,3};int min = array[0];//// 比武擂台for (int i = 1; i < array.length; i++) {// 如果当前元素,比min更小,则换人if(array[i]<min){min = array[i];}}// 谁最后最厉害,就能在max当中留下谁的战斗力System.out.println("最大值:"+min);}}
数组反转
- 数组的反转: 数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1

public class ArrayReverse {public static void main(String[] args) {int[] array = {23,45,56,2,35,46};//遍历数组原来的样子for (int i = 0; i < array.length; i++) {System.out.println(array[i]);}/*初始化语句: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;}// 反转后,遍历数组for (int i = 0; i < array.length; i++) {System.out.println(array[i]);}}}
二维数组
语法1
数据类型[][] 数组名 = {{...}, {...}, {...}};
int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
语法2
数据类型[][] 数组名 = 数据类型 [二维数组长度][二维数组中一维数组的长度];
int[][] arr2 = new int[2][2];//{{0,0},{0,0}}
二维数组遍历
public class TestArray15{public static void main(String[] args){//定义一个二维数组:int[][] arr = new int[3][];//本质上定义了一个一维数组,长度为3int[] a1 = {1,2,3};arr[0] = a1;arr[1] = new int[]{4,5,6,7};arr[2] = new int[]{9,10};//读取6这个元素://System.out.println(arr[1][2]);//对二维数组遍历://方式1:外层普通for循环+内层普通for循环:for(int i=0;i<arr.length;i++){for(int j=0;j<arr[i].length;j++){System.out.print(arr[i][j]+"\t");}System.out.println();}//方式2:外层普通for循环+内层增强for循环:for(int i=0;i<arr.length;i++){for(int num:arr[i]){System.out.print(num+"\t");}System.out.println();}//方式3:外层增强for循环+内层增强for循环:for(int[] a:arr){for(int num:a){System.out.print(num+"\t");}System.out.println();}//方式4:外层增强for循环+内层普通for循环:for(int[] a:arr){for(int i=0;i<a.length;i++){System.out.print(a[i]+"\t");}System.out.println();}}}
二维数组求和
int[][] arr2 = { {1,2},{3,4,5},{6,7,8,9,10} };int sum2 = 0;for (int i=0; i<arr2.length; i++) {for (int j=0; j<arr2[i].length; j++) {//System.out.println(arr2[i][j])sum2 += arr2[i][j];}}System.out.println("sum2= "+ sum2);}}
数组异常
1、**越界异常**
访问数组的元素时,索引不能超出0~length-1这个范围。ArrayIndexOutOfBoundsException
2、**空指针异常**
在使用变量引用一个数组时,变量必须指向一个有效的数组对象,如果该变量的值为null,则意味着没有指向任何数组,此时通过该变量访问数组的元素会出现空指针异常。
数组应用
删除指定位置上的元素
import java.util.Arrays;public class TestArray08{public static void main(String[] args){//功能:给定一个数组,删除下标为2元素//1.给定一个数组:int[] arr = {12,34,56,7,3,10,34,45,56,7,666};// 0 1 2 3 4 5//2.输出删除前的数组:System.out.println("删除元素前的数组:"+Arrays.toString(arr));//3.删除/*arr[2] = arr[3];arr[3] = arr[4];arr[4] = arr[5];*/int index = 0;for(int i=index;i<=arr.length-2;i++){arr[i] = arr[i+1];}arr[arr.length-1] = 0;//4.输出删除后的数组:System.out.println("删除元素后的数组:"+Arrays.toString(arr));}}
添加元素
public class TestArray07{public static void main(String[] args){//功能:给定一个数组,在数组下标为2的位置上添加一个元素91//1.给定一个数组:int[] arr = {12,34,56,7,3,10,55,66,77,88,999,89};// 0 1 2 3 4 5//2.输出增加元素前的数组:System.out.print("增加元素前的数组:");for(int i=0;i<arr.length;i++){if(i!=arr.length-1){System.out.print(arr[i]+",");}else{//i==arr.length-1 最后一个元素不用加,System.out.print(arr[i]);}}//3.增加元素/*arr[5] = arr[4];arr[4] = arr[3];arr[3] = arr[2];*/int index = 1;//在这个指定位置添加 元素for(int i=arr.length-1;i>=(index+1);i--){arr[i] = arr[i-1];}arr[index] = 666;//4.输出增加元素后的数组:System.out.print("\n增加元素后的数组:");for(int i=0;i<arr.length;i++){if(i!=arr.length-1){System.out.print(arr[i]+",");}else{//i==arr.length-1 最后一个元素不用加,System.out.print(arr[i]);}}}}
将添加功能提取为一个 方法
import java.util.Scanner;public class TestArray07{public static void main(String[] args){//功能:给定一个数组,在数组下标为2的位置上添加一个元素91//1.给定一个数组:int[] arr = {12,34,56,7,3,10,55,66,77,88,999,89};// 0 1 2 3 4 5//2.输出增加元素前的数组:/*System.out.print("增加元素前的数组:");for(int i=0;i<arr.length;i++){if(i!=arr.length-1){System.out.print(arr[i]+",");}else{//i==arr.length-1 最后一个元素不用加,System.out.print(arr[i]);}}*///从键盘接收数据:Scanner sc = new Scanner(System.in);System.out.println("请录入你要添加元素的指定下标:");int index = sc.nextInt();System.out.println("请录入你要添加的元素:");int ele = sc.nextInt();//3.增加元素//调用方法:insertEle(arr,index,ele);//4.输出增加元素后的数组:System.out.print("\n增加元素后的数组:");for(int i=0;i<arr.length;i++){if(i!=arr.length-1){System.out.print(arr[i]+",");}else{//i==arr.length-1 最后一个元素不用加,System.out.print(arr[i]);}}}/*提取一个添加元素的方法:在数组的指定位置上添加一个指定的元素。在哪个数组的哪个位置添加哪个元素!不确定因素:形参:哪个数组,哪个位置,哪个元素返回值:无*/public static void insertEle(int[] arr,int index,int ele){for(int i=arr.length-1;i>=(index+1);i--){arr[i] = arr[i-1];}arr[index] = ele;}}
数组最值的计算
方法1
public class TestArray03 {public static void main(String[] args) {int[] arr = { 4, 1, 6, 3, 9, 8 }; // 定义一个数组int max = arr[0]; // 定义变量max用于记住最大数,首先假设第一个元素为最大值// 下面通过一个for循环遍历数组中的元素for (int i = 1; i < arr.length; i++) {if (arr[i] > max) { // 比较 arr[x]的值是否大于maxmax = arr[i]; // 条件成立,将arr[x]的值赋给max}}System.out.println("max=" + max); // 打印最大值}}
方法2
public class TestArray04{public static void main(String[] args){int[] arr = {12,3,7,4,8,725,9,45,666,36}; //1.给定一个数组//2.求出数组中的最大值://调用方法:int num = getMaxNum(arr);System.out.println("当前数组中最大的数为:"+num);}/*想提取一个方法:求数组中的最大值*/public static int getMaxNum(int[] arr){int maxNum = arr[0];for(int i=0;i<arr.length;i++){if(arr[i]>maxNum){maxNum = arr[i];}}return maxNum;}}
数组查询
查询指定位置的元素
public class TestArray05{public static void main(String[] args){//查询指定位置的元素//给定一个数组:int[] arr = {12,34,56,7,3,10};//查找索引为2的位置上对应的元素是什么?System.out.println(arr[2]);}}
查询元素对应的索引
查询存在的索引
public class TestArray06 {public static void main(String[] args) {//找出元素对应的索引int[] arr = {12,34,56,7,3,56};//查询元素56对应的索引int index = 0;for (int i = 0; i < arr.length; i++) {if(arr[i]==56){index = i;//只要找到了元素,index就变成ibreak; // 只要找到这个元素,循环就停止}}System.out.println("元素对应的索引:"+index);//2}}
查询不存在的索引
出现问题
public class TestArray06 {public static void main(String[] args) {//找出元素对应的索引int[] arr = {12,34,56,7,3,56};//查询元素56对应的索引int index = 0;for (int i = 0; i < arr.length; i++) {if(arr[i]==900){index = i;//只要找到了元素,index就变成ibreak; // 只要找到这个元素,循环就停止}}System.out.println("元素对应的索引:"+index);//0}}
优化
public class TestArray06 {public static void main(String[] args) {//找出元素对应的索引int[] arr = {12,34,56,7,3,56};//查询元素56对应的索引int index = -1;//初始值不是数组的索引即可for (int i = 0; i < arr.length; i++) {if(arr[i]==900){index = i;//只要找到了元素,index就变成ibreak; // 只要找到这个元素,循环就停止}}if(index!=-1){System.out.println("元素对应的索引:"+index);} else{System.out.println("查无次数");}}}
将查指定元素对应的索引的功能提取为方法
public class TestArray06{public static void main(String[] args){int[] arr = {12,34,56,7,3,56}; //给定一个数组//调用方法:int index = getIndex(arr,999);//后续对index的值进行判断:if(index!=-1){System.out.println("元素对应的索引:"+index);}else{//index==-1System.out.println("查无次数!");}}/*定义一个方法:查询数组中指定的元素对应的索引不确定因素:哪个数组,哪个指定元素 (形参)返回值:索引*/public static int getIndex(int[] arr,int ele){int index = -1; //这个初始值只要不是数组的索引即可for(int i=0;i<arr.length;i++){if(arr[i]==ele){index = i;//只要找到了元素,那么index就变成为ibreak;//只要找到这个元素,循环就停止}}return index;}}
数组_可变参数
定义
1、使用...表示可变长参数
print(String... args){...}
2、在具有可变长参数的方法中可以把参数当成数组使用,例如可以循环输出所有的参数值
print(String... args){for(String temp:args)System.out.println(temp);}
可变参数作用
提供了一个方法,参数的个数是可变的 ,解决了部分方法的重载问题
可变长参数的方法的调用
调用的时候可以给出任意多个参数也可不给参数
print();print("hello");print("hello","lisi");print("hello","张三", "alexia")
注:可变参数和其他数据一起作为形参的时候,可变参数一定要放在最后
public class TestArray12{public static void main(String[] args){//method01(10);//method01();//method01(20,30,40);method01(30,40,50,60,70);//method01(new int[]{11,22,33,44});}public static void method01(int num2,int...num){System.out.println("-----1");for(int i:num){System.out.print(i+"\t");}System.out.println();System.out.println(num2);}}
