Java基础语法-第六节-数组

数组的概述

  • 数组(Array),是多个相同类型数据一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
  • 数组的常见概念
    • 数组名
    • 下标(或索引)
    • 元素
    • 数组的长度
  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 数组的长度一旦确定,就不能修改
  • 我们可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
  • 数组的分类:
    • 按照维度:一维数组、二维数组、三维数组、…
    • 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)

一维数组

  • 一维数组的声明方式:
type var[] 或 type[] var;
例如:int a[];
	int[] a1;
	double b[];
	String[] c; //引用类型变量数组
  • Java语言中声明数组时不能指定其长度(数组中元素的数), 例如: int a[5]; //非法

  • 动态初始化:数组声明且为数组元素分配空间与赋值的操作分开进行

    int[] arr = new int[3];
    arr[0] = 3;
    arr[1] = 9;
    arr[2] = 8;
    或
    String names[];
    names = new String[3];
    names[0] = “钱学森”;
    names[1] = “邓稼先”;
    names[2] = “袁隆平”;    
    
  • 静态初始化:在定义数组的同时就为数组元素分配空间并赋值。

    int arr[] = new int[]{ 3, 9, 8};或int[] arr = {3,9,8};
    String names[] = {“李四光”,“茅以升”,“华罗庚” }
    
  • 定义并用运算符new为之分配空间后,才可以引用数组中的每个元素;

  • 数组元素的引用方式:数组名[数组元素下标]

    • 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
    • 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
  • 每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)

    • 数组一旦初始化,其长度是不可变的
  • 数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。例如:

    int a[]= new int[5];
    System.out.println(a[3]); //a[3]的默认值为0
    
    • 对于基本数据类型而言,默认初始化值各有不同
    • 对于引用数据类型而言,默认初始化值为null(注意与0不同!
    数组元素类型 元素的默认初始化值
    byte 0
    short 0
    int 0
    long 0L
    float 0.0F
    double 0.0
    char 0或写为'u0000'(表现为空)
    boolean false
    引用类型 null
  • Java中使用关键字new来创建数组

    • 如下是创建基本数据类型元素的一维数组
    int[] s;
    s = new int[10];
    //int[] s=new int[10];
    //基本数据类型数组在显式赋值之前,
    //Java会自动给他们赋默认值。
    for ( int i=0; i<10; i++ ) {
        s[i] =2*i+1;
        System.out.println(s[i]);
    }
    
    • 执行int[] s;后的内存变化

    • 执行s = new int[10];后的内存变化

    • 执行 s[i] =2*i+1;后的内存变化

//1.一维数组的声明和初始化
int[] ids;//声明
//1.1静态初始化:数组的初始化和元素的赋值操作同时进行
ids = new int[] {1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//错误的写法
//int[] arr1 = new int[];
//int[5] arr2 = new int[];
//int[] arr3 = new int[3]{1,2,3};
//总结:数组一旦初始化完成,其长度就基本确定了

//2.如何调用数组的指定位置的元素:通过下标的方式调用
//数组的下标(或索引)从0开始的,到数组的长度-1结束
names[0] = "zhangsan";
names[1] = "lisi";
names[2] = "wangwu";
names[3] = "liuliu";
names[4] = "zhaoyun";

//3.如何获取数组的长度。
//属性:length
System.out.println(names.length);//5
System.out.println(ids.length);//4

//4.如何遍历数组
System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);
for(int i = 0;i < names.length;i++) {
    System.out.println(names[i]);
}

//5.数组元素的默认初始化值
int[] arr = new int[4];
for(int i = 0;i < arr.length;i++) {
    System.out.println(arr[i]);//输出0
}
char[] arr1 = new char[4];
for(int i = 0;i < arr1.length;i++) {
    System.out.println((int)arr1[i]);//0
}

多维数值

  • 对于二维数组的理解,我们可以看成是一维数array1又作为另一个一维数组array2的元素而存在。其实,从数组底层的运行机制来看,其实没有多维数组。

  • 二维数组[][]:数组中的数组。初始化方法

    • 格式1(动态初始化):int[][] arr = new int[3][2];

      • 定义了名称为arr的二维数组
      • 二维数组中有3个一维数组
      • 每一个一维数组中有2个元素
      • 一维数组的名称分别为arr[0], arr[1], arr[2]
      • 给第一个一维数组1脚标位赋值为78写法是:arr[0][1] = 78;
      • 格式2(动态初始化):int[][] arr = new int[3][];
      • 二维数组中有3个一维数组。
      • 每个一维数组都是默认初始化值null (注意:区别于格式1)
      • 可以对这个三个一维数组分别进行初始化
      arr[0] = new int[3]; 
      arr[1] = new int[1]; 
      arr[2] = new int[2];
      
      • 注:int[][] arr = new int[][3]; //非法
    • 格式3(静态初始化):int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};

      • 定义一个名称为arr的二维数组,二维数组中有三个一维数组
      • 每一个一维数组中具体元素也都已初始化
      • 第一个一维数组 arr[0] = {3,8,2};
      • 第二个一维数组 arr[1] = {2,7};
      • 第三个一维数组 arr[2] = {9,0,1,6};
      • 第三个一维数组的长度表示方式:arr[2].length;
  • 注意特殊写法情况:int[] x,y[]; x是一维数组,y是二维数组。

  • Java中多维数组不必都是规则矩阵形式

  • 内存的解析

//1.一维数组的声明和初始化
int[] arr = new int[] {1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{1,2},{1,2,3}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//错误的情况
//String[][] arr4 = new String[][4];
//String[4][3] arr5 = new String[][];
//int[][] arr6 = new int[4][3]{{1,2,3},{1,4,2},{1,2,3}};
//也是正确的
int[] arr4[] = new int[][]{{1,2,3},{1,2,3,4,5,6},{1,2,3}};
int[] arr5[] = {{1,2,3},{1,4,2},{1,2,3}};

//2.如何调用数组的指定位置的元素:
System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);

//3.如何获取数组的长度
System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//6

//4.如何遍历数组
for (int i = 0; i < arr4.length; i++) {
    for (int j = 0; j < arr4[i].length; j++) {
        System.out.print(arr4[i][j]+" ");
    }
    System.out.println();
}

//5.数组元素的默认初始化值
int[][] arr9 = new int[4][3];
System.out.println(arr9);//[[I@15db9742  地址值,左边有两个[
System.out.println(arr9[0]);//[I@6d06d69c  地址值,左边有一个[
System.out.println(arr9[0][0]);//0
double[][] ar1 = new double[4][3];
System.out.println(ar1);//[[D@7852e922  地址值,左边有两个[
System.out.println(ar1[0]);//[D@4e25154f  地址值,左边有一个[
System.out.println(ar1[0][0]);//0.0
String[][] ar2 = new String[4][3];
System.out.println(ar2);//[[Ljava.lang.String;@70dea4e  地址值,左边有两个[
System.out.println(ar2[0]);//[Ljava.lang.String;@5c647e05  地址值,左边有一个[
System.out.println(ar2[0][0]);//null

String[][] ar3 = new String[4][];
System.out.println(ar3);//[[Ljava.lang.String;@33909752  地址值,左边有两个[
System.out.println(ar3[0]);//null 
//System.out.println(ar3[0][0]);//报错
double[][] ar4 = new double[4][];
System.out.println(ar4);//[[D@55f96302  地址值,左边有两个[
System.out.println(ar4[0]);//null
//System.out.println(ar4[0][0]);//报错

数组中涉及到的常见算法

  • 数组元素的赋值(杨辉三角、回形数等)

    //杨辉三角
    /*
    * 1 
    * 1 1 
    * 1 2 1 
    * 1 3 3 1 
    * 1 4 6 4 1 
    * 1 5 10 10 5 1 
    * 1 6 15 20 15 6 1
    */
    //1.声明并初始化二维数组
    int[][] yangHui = new int[10][];
    //2.给数组的元素赋值
    for (int i = 0; i < yangHui.length; i++) {
        yangHui[i]= new int[i+1];
    
        //2.1给首末元素赋值
        yangHui[i][0] = yangHui[i][i]= 1;
        //2.2给每行的非首末元素赋值
        for (int j = 1; j < yangHui[i].length-1; j++) {
            yangHui[i][j]= yangHui[i-1][j-1] + yangHui[i-1][j]; 
        }
    }
    //3.遍历二维数组
    for (int i = 0; i < yangHui.length; i++) {
        for (int j = 0; j < yangHui[i].length; j++) {
            System.out.print(yangHui[i][j]+" ");
        }
        System.out.println();
    }
    //回形数
    /*
    *1   2   3   4 
    *12  13  14  5 
    *11  16  15  6 
    *10   9  8    7
    */
    int n = 4;
    int[][] arr = new int[n][n];
    int count = 0; //要显示的数据
    int maxX = n-1; //X轴的最大下标
    int maxY = n-1; //Y轴的最大下标
    int minX = 0; //X轴的最小下标
    int minY = 0; //Y轴的最小下标
    while(minX <= maxX) {
        for (int i = minX; i <= maxX; i++) {
            arr[minY][i] = ++count; 
        }
        minY++;
        for (int i = minY; i <= maxY; i++) {
            arr[i][maxX] = ++count; 
        }
        maxX--;
        for (int i = maxX; i >= minX; i--) {
            arr[maxY][i]= ++count;
        }
        maxY--;
        for (int i = maxY; i >= minY; i--) {
            arr[i][minX] = ++count;
        }
        minX++;
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr.length; j++) {
            String space = (arr[i][j] + " ").length() ==1 ? "0" : "";
            System.out.print(space + arr[i][j] + " " );
        }
        System.out.println();
    }
    
  • 求数值型数组中元素的最大值、最小值、平均数、总和等

    //定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
    //然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
    //要求:所有随机数都是两位数。
    //初始化数组
    int[] arr = new int[10];
    for (int i = 0; i < arr.length; i++) {
        arr[i] = (int)(Math.random() * (99 - 10 + 1) + 10); 
    }
    //遍历数组
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+ " ");
    }
    System.out.println();
    //求数组的最大值
    int maxValue = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if(maxValue < arr[i]) {
            maxValue = arr[i];
        }
    }
    System.out.println("最大值: " + maxValue);
    //求数组元素的最小值
    int minValue = arr[0];
    for (int i = 1; i < arr.length; i++) {
        if(minValue > arr[i]) {
            minValue = arr[i];
        }
    }
    System.out.println("最小值: " + minValue);
    //求数组元素的和
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    System.out.println("和: " + sum);
    //求数组元素的平均数
    double avgValue = (double)sum/arr.length;
    System.out.println("平均数: " + avgValue);
    
  • 数组的复制、反转、查找(线性查找、二分法查找)

    int[] arr1 = new int[] {1,2,3,4,5,6,7,8};
    //复制 
    int[] arr2 = new int[arr1.length];
    for (int i = 0; i < arr2.length; i++) {
        arr2[i]= arr1[i]; 
    }
    //反转
    for(int i = 0,j = arr1.length - 1;i < j;i++,j--) {
        int temp = arr1[i];
        arr1[i] = arr1[j];
        arr1[j] = temp;  
    }
    //查找
    //1.线性查找
    int dest = 6;//目标值
    int flag = false;
    for (int i = 0; i < arr1.length; i++) {
        if(arr1[i] == dest) {
            System.out.println("找到了,下标为:"+i);
    		flag = true;
            break;
        }
    }
    if(flag){
         System.out.println("没找到");
    }
    //2.二分查找:前提是查找的数组必须是有序的
    int dest = 6;//目标值
    int left = 0;//初始的首索引
    int right = arr1.length - 1;//初始的末索引
    while(left < right) {
        int mid = (right + left) / 2;
        if(dest == arr1[mid]) {
            System.out.println("找到了,下标为:"+i);
        }else if(arr1[mid] > dest) {
            right = mid - 1;
        }else {
            left = mid + 1;
        }
    }
    
  • 数组元素的排序算法

    int[] arr = new int[] {1,5,9,3,8,7,6,4,2};
    //冒泡排序
    for (int i = 0; i < arr.length - 1; i++) {
        boolean flag = true;
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if(arr[j]> arr[j + 1]) {
                flag = false;
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
        if(flag) {
            break;
        }
    }
    

Arrays工具类的使用

  • java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

    boolean equals(int[] a,int[] b) 判断两个数组是否相等。
    void fill(int[] a,int val) 将指定值填充到数组之中。
    void sort(int[] a) 对数组进行排序。
    String toString(int[] a) 输出数组信息。
    int binarySearch(int[] a,int key) 对排序后的数组进行二分法检索指定的值。
    //boolean equals(int[] a,int[] b)
    int[] arr = new int[] {1,2,3,4};
    int[] arr2 = new int[] {1,5,3,8};
    boolean isEquals = Arrays.equals(arr, arr2);
    System.out.println(isEquals);//false
    //void fill(int[] a,int val)
    Arrays.fill(arr, 0);
    //String toString(int[] a)
    System.out.println(Arrays.toString(arr));//[0, 0, 0, 0]
    //void sort(int[] a)
    Arrays.sort(arr2);
    System.out.println(Arrays.toString(arr2));//[1, 3, 5, 8]
    //int binarySearch(int[] a,int key)
    int index = Arrays.binarySearch(arr2, 5);
    System.out.println(index);//2
    

数组使用中的常见异常

数组脚标越界异常( ArrayIndexOutOfBoundsException)
int[] arr = new int[2];
System.out.println(arr[2]);
System.out.println(arr[-1]);
访问到了数组中的不存在的脚标时发生。
空指针异常(NullPointerException)
int[] arr = null;
System.out.println(arr[0]);
arr引用没有指向实体,却在操作实体中的元素时。

总结

/*
 * 一:数组的概述
 * 	1.数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
 * 	2.数组相关的概念
 * 		>数组名
 * 		>元素
 *  	>角标,下标,索引
 *  	>数组的长度,元素的个数
 *  3.数组的特点。
 *  	1)数组是有序排列的
 *  	2)数组属于引用数据类型的变量。数组的元素既可以是基本数据类型,也可以是引用数据类型
 *  	3)创建数组对象会在内存中开辟一整块连续的内存空间
 *  	4)数组的长度一旦确定,就不能改变
 *  4.数组的分类
 *  	①按照维数:一维数组,二维数组。。。
 *  	②按照数组元素的类型:基本数据类型元素的数组,引用数据类型元素的数组
 *  5.一维数组的使用
 *  	①一维数组的声明和初始化
 *  	②如何调用数组的指定位置的元素
 *  	③如何获取数组的长度
 *  	④如何遍历数组
 *  	⑤数组元素的默认初始化值
 *  		>数组元素是整型:0
 *  		>数组元素是浮点型:0.0
 *  		>数组元素是char型:0(ASCII码)或'u0000'
 *  		>数组元素是boolean型:false
 *  		>数组元素是引用数据型:null
 *  	⑥数组的内存解析
 *  6.二维数组的使用
 *  	对于二维数组的理解,我们可以看成是一维数组array1又作为另一个一维数组array2的元素而存在。
 *  	其实,从数组底层的运行机制来看,其实没有多维数组.
 *  	二维数组的元素分为外层数组的元素和内层数组的元素
 *  	int[][] arr = new int[4][3];
 *  	外层数组元素:arr[0],arr[1]等
 *  	内层数组元素:arr[0][0],arr[1][1]等
 *		①一维数组的声明和初始化
 *  	②如何调用数组的指定位置的元素
 *  	③如何获取数组的长度
 *  	④如何遍历数组
 *  	⑤数组元素的默认初始化值
 *  	针对与初始化方式一:例如:int[][] arr9 = new int[4][3];
 *  		外层元素的初始值为:地址值
 *  		内层元素的初始值为:与一维数组初始情况相同
 *  	针对于初始化方式二:例如:int[][] arr9 = new int[4][];	
 *  		外层元素的初始值为:null
 *  		内层元素的初始值为:不能调用,否则报错
 *  	⑥数组的内存解析
 */
原文地址:https://www.cnblogs.com/mzchuan/p/13885853.html