数组

数组指一组数据的集合,数组中的每个数据被称作元素

特点

  1. 数组是一种引用数据类型
  2. 长度确定,定义的时候必须指定数组的长度
  3. 类型确定,定义的时候必须声明数组的类型

数组的初始化

在内存当中创建一个数组,并且向其中赋予一些默认值。

分类

  1. 一维数组
  2. 多维数组

一维数组

两种常见的初始化方式:

  • 动态初始化(指定长度):在创建数组的时候,直接指定数组当中的数据元素个数。
  • 静态初始化(指定内容):在创建数组的时候,不直接指定数据个数多少,而是直接将具体的数据内容进行指定。

动态初始化

动态初始化:创建一个数组,但是没有初始化数组的元素。这种情况需要显式的指定数组大小。

数据类型[ ] 数组名 = new 数据类型[数组长度];

解析含义: 左侧数据类型:也就是数组当中保存的数据,全都是统一的什么类型 左侧的中括号:代表我是一个数组 左侧数组名称:给数组取一个名字 右侧的new:代表创建数组的动作 右侧数据类型:必须和左边的数据类型保持一致 右侧中括号的长度:也就是数组当中,到底可以保存多少个数据,是一个int数字

  1. public class Demo01Array {
  2. public static void main(String[] args) {
  3. // 创建一个数组,里面可以存放300个int数据
  4. // 格式:数据类型[] 数组名称 = new 数据类型[数组长度];
  5. int[] arrayA = new int[300];
  6. // 创建一个数组,能存放10个double类型的数据
  7. double[] arrayB = new double[10];
  8. // 创建一个数组,能存放5个字符串
  9. String[] arrayC = new String[5];
  10. }
  11. }

静态初始化

创建一个数组,并已知数组的内部元素

标准格式:
数据类型[] 数组名称 = new 数据类型[] { 元素1, 元素2, ... };

省略格式:
数据类型[] 数组名 = {...};

  1. int[] myArr = {0,1,2};
  1. public class ArrayDemo {
  2. public static void main(String[] args) {
  3. /*
  4. * 定义语法1
  5. * 数据类型[ ] 数组名 = new 数据类型[size];
  6. * 定义语法2
  7. * 数据类型[ ] 数组名 = {数据1,数据2,数据3};
  8. **/
  9. int[] myArr = new int[3];
  10. System.out.println(myArr[2]);
  11. int[] myArr1 = {100, 200, 300};
  12. System.out.println(myArr1[1]);
  13. // 数组长度
  14. // 最大索引 = 数组长度 - 1
  15. System.out.println(myArr.length);
  16. System.out.println(myArr1.length);
  17. }
  18. }

注意事项
1. 静态初始化没有直接指定长度,但是仍然会自动推算得到长度。
2. 静态初始化标准格式可以拆分成为两个步骤。
3. 动态初始化也可以拆分成为两个步骤。
4. 静态初始化一旦使用省略格式,就不能拆分成为两个步骤了。

  1. public class Demo03Array {
  2. public static void main(String[] args) {
  3. // 省略格式的静态初始化
  4. int[] arrayA = { 10, 20, 30 };
  5. // 2.静态初始化的标准格式,可以拆分成为两个步骤
  6. int[] arrayB;
  7. arrayB = new int[] { 11, 21, 31 };
  8. // 3.动态初始化也可以拆分成为两个步骤
  9. int[] arrayC;
  10. arrayC = new int[5];
  11. // 4.静态初始化的省略格式,不能拆分成为两个步骤。
  12. // int[] arrayD;
  13. // arrayD = { 10, 20, 30 };
  14. }
  15. }

使用建议:

  • 如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化

数组的默认初始值

数组类型 默认初始化
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) {

    1. // 静态初始化的省略格式
    2. int[] array = { 10, 20, 30 };
    3. System.out.println(array); // [I@6e0be858
    4. // 直接打印数组当中的元素
    5. System.out.println(array[0]); // 10
    6. System.out.println(array[1]); // 20
    7. System.out.println(array[2]); // 30
    8. System.out.println("=============");
    9. // 也可以将数组当中的某一个单个元素,赋值交给变量
    10. int num = array[1];
    11. System.out.println(num); // 20

    }

}

  1. <a name="dHCaB"></a>
  2. ### 内存概述
  3. 内存是计算机中的重要原件,临时存储区域,作用是运行程序。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。 <br />Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。
  4. **JVM的内存划分**
  5. | **区域名称** | **作用** |
  6. | --- | --- |
  7. | 方法栈 | 方法运行时使用的内存,比如main方法运行,进入方法栈中执行,存放的都是方法中的`局部变量` |
  8. | <br /><br />堆内存 | 存储对象或者数组,凡是`new`出来的东西,都在堆中<br />- 堆内存的东西都有一个地址值:`16进制`<br />- 堆内存里面的数据都有`默认值`<br /> |
  9. | 方法区 | 存储`.class`相关信息,包含方法的信息 |
  10. | 本地方法栈 | JVM在使用操作系统功能的时候使用 |
  11. | 寄存器 | 与`cpu`相关 |
  12. <a name="HhbWJ"></a>
  13. ### 数组在内存中的存储
  14. > <a name="WQNTh"></a>
  15. #### 一个数组内存图
  16. ```java
  17. public class Demo02 {
  18. public static void main(String[] args) {
  19. int[] arr = new int[3];
  20. System.out.println(arr);//[I@6e0be858
  21. }
  22. }

以上方法执行,输出结果[I@6e0be858,是数组在内存中的地址。new出来的内容,都是在堆内存中存储的,而方法中的变量arr保存的是数组的地址。

第6章:数组 - 图1
程序执行流程:

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

image.png

两个数组内存图

  1. public class Demo02 {
  2. public static void main(String[] args) {
  3. int[] arr = new int[3];
  4. int[] arr2 = new int[2];
  5. System.out.println(arr);//[I@6e0be858
  6. System.out.println(arr2);//[I@61bbe9ba
  7. }
  8. }

image.png
image.png

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

image.png

获取数组长度

格式:数组名称.length

  1. public class ArrayLength {
  2. public static void main(String[] args) {
  3. int[] array = {12,23,43,55,6,7,2,3,3,4,6};
  4. int len = array.length;
  5. System.out.println("array数组的长度是:" + len);
  6. }

数组一旦创建,程序运行期间,长度不可改变,意思是new出来的长度不可改变

  1. public class ArrayLength {
  2. public static void main(String[] args) {
  3. int[] array = new int[3];
  4. System.out.println(array.length); // 3
  5. array = new int[5];
  6. System.out.println(array.length); // 5
  7. }
  8. }

以上是变量array被赋值,并不少改变new出来数组长度

image.png

数组遍历

  1. public class TestArray03 {
  2. public static void main(String[] args) {
  3. int[] arr = { 1, 2, 3, 4, 5 }; // 定义数组
  4. // 使用for循环遍历数组的元素
  5. for (int i = 0; i < arr.length; i++) {
  6. System.out.println(arr[i]); // 通过索引访问元素
  7. }
  8. }
  9. }

数组最值

最大值

  1. public class DemoMax {
  2. public static void main(String[] args) {
  3. int[] array = {1,34,56,68,4,32,3};
  4. int max = array[0];//// 比武擂台
  5. for (int i = 1; i < array.length; i++) {
  6. // 如果当前元素,比max更大,则换人
  7. if(array[i]>max){
  8. max = array[i];
  9. }
  10. }
  11. // 谁最后最厉害,就能在max当中留下谁的战斗力
  12. System.out.println("最大值:"+max);
  13. }
  14. }

最小值

  1. public class DemoMin {
  2. public static void main(String[] args) {
  3. int[] array = {1,34,56,68,4,32,3};
  4. int min = array[0];//// 比武擂台
  5. for (int i = 1; i < array.length; i++) {
  6. // 如果当前元素,比min更小,则换人
  7. if(array[i]<min){
  8. min = array[i];
  9. }
  10. }
  11. // 谁最后最厉害,就能在max当中留下谁的战斗力
  12. System.out.println("最大值:"+min);
  13. }
  14. }

数组反转

  • 数组的反转: 数组中的元素颠倒顺序,例如原始数组为1,2,3,4,5,反转后的数组为5,4,3,2,1

image.png

  1. public class ArrayReverse {
  2. public static void main(String[] args) {
  3. int[] array = {23,45,56,2,35,46};
  4. //遍历数组原来的样子
  5. for (int i = 0; i < array.length; i++) {
  6. System.out.println(array[i]);}
  7. /*
  8. 初始化语句:int min = 0, max = array.length - 1
  9. 条件判断:min < max
  10. 步进表达式:min++, max--
  11. 循环体:用第三个变量倒手
  12. */
  13. for (int min =0,max = array.length-1;min<max;min++,max--) {
  14. //利用第三方变量完成数组中的元素交换
  15. int temp = array[min];
  16. array[min] = array[max];
  17. array[max] = temp;
  18. }
  19. // 反转后,遍历数组
  20. for (int i = 0; i < array.length; i++) {
  21. System.out.println(array[i]);
  22. }
  23. }
  24. }

二维数组

语法1

数据类型[][] 数组名 = {{...}, {...}, {...}};

  1. int[][] arr = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

语法2

数据类型[][] 数组名 = 数据类型 [二维数组长度][二维数组中一维数组的长度];

  1. int[][] arr2 = new int[2][2];//{{0,0},{0,0}}

二维数组遍历

  1. public class TestArray15{
  2. public static void main(String[] args){
  3. //定义一个二维数组:
  4. int[][] arr = new int[3][];//本质上定义了一个一维数组,长度为3
  5. int[] a1 = {1,2,3};
  6. arr[0] = a1;
  7. arr[1] = new int[]{4,5,6,7};
  8. arr[2] = new int[]{9,10};
  9. //读取6这个元素:
  10. //System.out.println(arr[1][2]);
  11. //对二维数组遍历:
  12. //方式1:外层普通for循环+内层普通for循环:
  13. for(int i=0;i<arr.length;i++){
  14. for(int j=0;j<arr[i].length;j++){
  15. System.out.print(arr[i][j]+"\t");
  16. }
  17. System.out.println();
  18. }
  19. //方式2:外层普通for循环+内层增强for循环:
  20. for(int i=0;i<arr.length;i++){
  21. for(int num:arr[i]){
  22. System.out.print(num+"\t");
  23. }
  24. System.out.println();
  25. }
  26. //方式3:外层增强for循环+内层增强for循环:
  27. for(int[] a:arr){
  28. for(int num:a){
  29. System.out.print(num+"\t");
  30. }
  31. System.out.println();
  32. }
  33. //方式4:外层增强for循环+内层普通for循环:
  34. for(int[] a:arr){
  35. for(int i=0;i<a.length;i++){
  36. System.out.print(a[i]+"\t");
  37. }
  38. System.out.println();
  39. }
  40. }
  41. }

二维数组求和

  1. int[][] arr2 = { {1,2},{3,4,5},{6,7,8,9,10} };
  2. int sum2 = 0;
  3. for (int i=0; i<arr2.length; i++) {
  4. for (int j=0; j<arr2[i].length; j++) {
  5. //System.out.println(arr2[i][j])
  6. sum2 += arr2[i][j];
  7. }
  8. }
  9. System.out.println("sum2= "+ sum2);
  10. }
  11. }

数组异常

1、**越界异常**
访问数组的元素时,索引不能超出0~length-1这个范围。ArrayIndexOutOfBoundsException
2、**空指针异常**
在使用变量引用一个数组时,变量必须指向一个有效的数组对象,如果该变量的值为null,则意味着没有指向任何数组,此时通过该变量访问数组的元素会出现空指针异常。

数组应用

删除指定位置上的元素

  1. import java.util.Arrays;
  2. public class TestArray08{
  3. public static void main(String[] args){
  4. //功能:给定一个数组,删除下标为2元素
  5. //1.给定一个数组:
  6. int[] arr = {12,34,56,7,3,10,34,45,56,7,666};
  7. // 0 1 2 3 4 5
  8. //2.输出删除前的数组:
  9. System.out.println("删除元素前的数组:"+Arrays.toString(arr));
  10. //3.删除
  11. /*
  12. arr[2] = arr[3];
  13. arr[3] = arr[4];
  14. arr[4] = arr[5];
  15. */
  16. int index = 0;
  17. for(int i=index;i<=arr.length-2;i++){
  18. arr[i] = arr[i+1];
  19. }
  20. arr[arr.length-1] = 0;
  21. //4.输出删除后的数组:
  22. System.out.println("删除元素后的数组:"+Arrays.toString(arr));
  23. }
  24. }

添加元素

  1. public class TestArray07{
  2. public static void main(String[] args){
  3. //功能:给定一个数组,在数组下标为2的位置上添加一个元素91
  4. //1.给定一个数组:
  5. int[] arr = {12,34,56,7,3,10,55,66,77,88,999,89};
  6. // 0 1 2 3 4 5
  7. //2.输出增加元素前的数组:
  8. System.out.print("增加元素前的数组:");
  9. for(int i=0;i<arr.length;i++){
  10. if(i!=arr.length-1){
  11. System.out.print(arr[i]+",");
  12. }else{//i==arr.length-1 最后一个元素不用加,
  13. System.out.print(arr[i]);
  14. }
  15. }
  16. //3.增加元素
  17. /*
  18. arr[5] = arr[4];
  19. arr[4] = arr[3];
  20. arr[3] = arr[2];
  21. */
  22. int index = 1;//在这个指定位置添加 元素
  23. for(int i=arr.length-1;i>=(index+1);i--){
  24. arr[i] = arr[i-1];
  25. }
  26. arr[index] = 666;
  27. //4.输出增加元素后的数组:
  28. System.out.print("\n增加元素后的数组:");
  29. for(int i=0;i<arr.length;i++){
  30. if(i!=arr.length-1){
  31. System.out.print(arr[i]+",");
  32. }else{//i==arr.length-1 最后一个元素不用加,
  33. System.out.print(arr[i]);
  34. }
  35. }
  36. }
  37. }

将添加功能提取为一个 方法

  1. import java.util.Scanner;
  2. public class TestArray07{
  3. public static void main(String[] args){
  4. //功能:给定一个数组,在数组下标为2的位置上添加一个元素91
  5. //1.给定一个数组:
  6. int[] arr = {12,34,56,7,3,10,55,66,77,88,999,89};
  7. // 0 1 2 3 4 5
  8. //2.输出增加元素前的数组:
  9. /*
  10. System.out.print("增加元素前的数组:");
  11. for(int i=0;i<arr.length;i++){
  12. if(i!=arr.length-1){
  13. System.out.print(arr[i]+",");
  14. }else{//i==arr.length-1 最后一个元素不用加,
  15. System.out.print(arr[i]);
  16. }
  17. }
  18. */
  19. //从键盘接收数据:
  20. Scanner sc = new Scanner(System.in);
  21. System.out.println("请录入你要添加元素的指定下标:");
  22. int index = sc.nextInt();
  23. System.out.println("请录入你要添加的元素:");
  24. int ele = sc.nextInt();
  25. //3.增加元素
  26. //调用方法:
  27. insertEle(arr,index,ele);
  28. //4.输出增加元素后的数组:
  29. System.out.print("\n增加元素后的数组:");
  30. for(int i=0;i<arr.length;i++){
  31. if(i!=arr.length-1){
  32. System.out.print(arr[i]+",");
  33. }else{//i==arr.length-1 最后一个元素不用加,
  34. System.out.print(arr[i]);
  35. }
  36. }
  37. }
  38. /*
  39. 提取一个添加元素的方法:
  40. 在数组的指定位置上添加一个指定的元素。
  41. 在哪个数组的哪个位置添加哪个元素!
  42. 不确定因素:形参:哪个数组,哪个位置,哪个元素
  43. 返回值:无
  44. */
  45. public static void insertEle(int[] arr,int index,int ele){
  46. for(int i=arr.length-1;i>=(index+1);i--){
  47. arr[i] = arr[i-1];
  48. }
  49. arr[index] = ele;
  50. }
  51. }

数组最值的计算

方法1

  1. public class TestArray03 {
  2. public static void main(String[] args) {
  3. int[] arr = { 4, 1, 6, 3, 9, 8 }; // 定义一个数组
  4. int max = arr[0]; // 定义变量max用于记住最大数,首先假设第一个元素为最大值
  5. // 下面通过一个for循环遍历数组中的元素
  6. for (int i = 1; i < arr.length; i++) {
  7. if (arr[i] > max) { // 比较 arr[x]的值是否大于max
  8. max = arr[i]; // 条件成立,将arr[x]的值赋给max
  9. }
  10. }
  11. System.out.println("max=" + max); // 打印最大值
  12. }
  13. }

方法2

  1. public class TestArray04{
  2. public static void main(String[] args){
  3. int[] arr = {12,3,7,4,8,725,9,45,666,36}; //1.给定一个数组
  4. //2.求出数组中的最大值:
  5. //调用方法:
  6. int num = getMaxNum(arr);
  7. System.out.println("当前数组中最大的数为:"+num);
  8. }
  9. /*
  10. 想提取一个方法:求数组中的最大值
  11. */
  12. public static int getMaxNum(int[] arr){
  13. int maxNum = arr[0];
  14. for(int i=0;i<arr.length;i++){
  15. if(arr[i]>maxNum){
  16. maxNum = arr[i];
  17. }
  18. }
  19. return maxNum;
  20. }
  21. }

数组查询

查询指定位置的元素

  1. public class TestArray05{
  2. public static void main(String[] args){
  3. //查询指定位置的元素
  4. //给定一个数组:
  5. int[] arr = {12,34,56,7,3,10};
  6. //查找索引为2的位置上对应的元素是什么?
  7. System.out.println(arr[2]);
  8. }
  9. }

查询元素对应的索引

查询存在的索引

  1. public class TestArray06 {
  2. public static void main(String[] args) {
  3. //找出元素对应的索引
  4. int[] arr = {12,34,56,7,3,56};
  5. //查询元素56对应的索引
  6. int index = 0;
  7. for (int i = 0; i < arr.length; i++) {
  8. if(arr[i]==56){
  9. index = i;//只要找到了元素,index就变成i
  10. break; // 只要找到这个元素,循环就停止
  11. }
  12. }
  13. System.out.println("元素对应的索引:"+index);//2
  14. }
  15. }

查询不存在的索引
出现问题

  1. public class TestArray06 {
  2. public static void main(String[] args) {
  3. //找出元素对应的索引
  4. int[] arr = {12,34,56,7,3,56};
  5. //查询元素56对应的索引
  6. int index = 0;
  7. for (int i = 0; i < arr.length; i++) {
  8. if(arr[i]==900){
  9. index = i;//只要找到了元素,index就变成i
  10. break; // 只要找到这个元素,循环就停止
  11. }
  12. }
  13. System.out.println("元素对应的索引:"+index);//0
  14. }
  15. }

优化

  1. public class TestArray06 {
  2. public static void main(String[] args) {
  3. //找出元素对应的索引
  4. int[] arr = {12,34,56,7,3,56};
  5. //查询元素56对应的索引
  6. int index = -1;//初始值不是数组的索引即可
  7. for (int i = 0; i < arr.length; i++) {
  8. if(arr[i]==900){
  9. index = i;//只要找到了元素,index就变成i
  10. break; // 只要找到这个元素,循环就停止
  11. }
  12. }
  13. if(index!=-1){
  14. System.out.println("元素对应的索引:"+index);
  15. } else{
  16. System.out.println("查无次数");
  17. }
  18. }
  19. }

将查指定元素对应的索引的功能提取为方法

  1. public class TestArray06{
  2. public static void main(String[] args){
  3. int[] arr = {12,34,56,7,3,56}; //给定一个数组
  4. //调用方法:
  5. int index = getIndex(arr,999);//后续对index的值进行判断:
  6. if(index!=-1){
  7. System.out.println("元素对应的索引:"+index);
  8. }else{//index==-1
  9. System.out.println("查无次数!");
  10. }
  11. }
  12. /*
  13. 定义一个方法:查询数组中指定的元素对应的索引
  14. 不确定因素:哪个数组,哪个指定元素 (形参)
  15. 返回值:索引
  16. */
  17. public static int getIndex(int[] arr,int ele){
  18. int index = -1; //这个初始值只要不是数组的索引即可
  19. for(int i=0;i<arr.length;i++){
  20. if(arr[i]==ele){
  21. index = i;//只要找到了元素,那么index就变成为i
  22. break;//只要找到这个元素,循环就停止
  23. }
  24. }
  25. return index;
  26. }
  27. }

数组_可变参数

定义

1、使用...表示可变长参数

  1. print(String... args){
  2. ...}

2、在具有可变长参数的方法中可以把参数当成数组使用,例如可以循环输出所有的参数值

  1. print(String... args){
  2. for(String temp:args)
  3. System.out.println(temp);
  4. }

可变参数作用

提供了一个方法,参数的个数是可变的 ,解决了部分方法的重载问题

可变长参数的方法的调用

调用的时候可以给出任意多个参数也可不给参数

  1. print();
  2. print("hello");
  3. print("hello","lisi");
  4. print("hello","张三", "alexia")

注:可变参数和其他数据一起作为形参的时候,可变参数一定要放在最后

  1. public class TestArray12{
  2. public static void main(String[] args){
  3. //method01(10);
  4. //method01();
  5. //method01(20,30,40);
  6. method01(30,40,50,60,70);
  7. //method01(new int[]{11,22,33,44});
  8. }
  9. public static void method01(int num2,int...num){
  10. System.out.println("-----1");
  11. for(int i:num){
  12. System.out.print(i+"\t");
  13. }
  14. System.out.println();
  15. System.out.println(num2);
  16. }
  17. }