Java中数组的使用

Java中数组的使用

介绍Java中数组的基本使用及需要注意的细节,对Java虚拟机的内存划分及数组在内存中的存储进行分析。

Author: Msuenb

Date: 2023-02-06


数组的概念

数组就是有限相同数据类型的元素按照一定顺序排列的集合。数组中元素的编号称为下标/索引,数组中元素的个数称为数组的长度。

数组的特点:

  • 数组长度一旦确定就不能修改
  • 创建数组时会在内存中开辟一整块连续的空间

数组的分类

按照维度分

  • 一维数组:存储一组数据
  • 二维数组:存储多组数据,相当于一个二维表。二维数组每一行对应一个一维数组,不要求每一行的长度都一样

按照存储元素类型分

  • 基本数据类型元素:存储数据值
  • 引用数据类型元素:存储对象引用(即该对象所在内存空间的首地址)

数组的声明与使用

主要是介绍一维数组的声明与使用,对于二维数组,可以看作多个一维数组的复合。其实,从数组底层的运行机制来看,并没有二维数组的存在。

一维数组的声明
  • 一维数组的声明语法

    Type[] name;	// 推荐
    Type name[];	// 不推荐
    
  • 数组在声明时需要确定三部分内容:元素类型(int、String...)、维度([]、[][])、名称

  • 一维数组声明示例

    int[] scores;
    System.out.println(scores);	// 数组未初始化之前 不能使用
    
    double prices[];	// 可以 不推荐
    
    String[] names;
    
一维数组的初始化

初始化就是确定数组长度元素的值。数组初始化有两种方式:静态初始化和动态初始化。

  1. 静态初始化

    静态初始化就是用静态数据为数组初始化。此时数组长度由静态数据的个数决定。

    • 一维数组静态初始化格式1:

      Type[] name = {element1, element2, elenent3...};	// 必须在一个语句中完成 不能分开两个语句写
      

      一维数组静态初始化实例1

      int[] arr = {7, 4, 2, 6, 9};	// 正确
      
      int[] arr;
      arr = {7, 4, 2, 6, 9};			// 错误
      
    • 一维数组静态初始化格式2:

      Type[] name = new Type[] {element1, element2, elelent3...};	// 可以分开 两个语句完成
      或
      Type[] name;
      name = new Type[] {element1, element2, elelent3...};
      

      一维数组静态初始化示例2

      int[] arr = new int[] {7, 4, 2, 6, 9};	// 正确
      
      int[] arr;
      arr = new int[] {7, 4, 2, 6, 9};	// 正确
      
  2. 动态初始化

    动态初始化就是先确定数组的长度,此时元素只是默认值,并不是真正的数据。真正的数据需要后续单独一个一个赋值。

    • 一维数组动态初始化格式

      Type[] name = new Type[length];	// length为数组的长度 即该数组能够存储数据的个数
      或
      Type[] name;
      name = new Type[length];
      

      一维数组动态初始化示例

      int[] arr = new int[5];
      
      int[] arr;
      arr = new int[5];
      
      int[] arr = new int[5] {1, 2, 3, 4, 5};//错误的,后面有{}指定元素列表,就不需要在[]中指定元素个数了。
      
    • 关于动态初始化时元素的默认值

      数据元素类型 元素默认初值
      byte、short、int 0
      long 0L
      float 0.0F
      double 0.0
      char 0 或写为 '\u0000'
      boolean false
      引用类型 null
一维数组的使用
  • 如何获取数组长度(即数组中元素的个数)

    Type[] name = {1, 2, 3, 4, 5}
    name.length;	// 通过 数组名.length 获取数组的长度
    
  • 如何表示数组中的一个元素?

    name[index];	// 通过 数组名[下标/索引] 访问某个元素
    

    Java中数组的下标范围:[0 ~ name.length-1]

  • 一维数组的使用演示

    public class Main {
        public static void main(String[] args) {
            int[] arr = {1, 2, 3, 4, 5};
    
            System.out.println("arr数组的长度:" + arr.length);
            System.out.println("arr数组的第1个元素:" + arr[0]);//下标从0开始
            System.out.println("arr数组的第2个元素:" + arr[1]);
            System.out.println("arr数组的第3个元素:" + arr[2]);
            System.out.println("arr数组的第4个元素:" + arr[3]);
            System.out.println("arr数组的第5个元素:" + arr[4]);
            
            System.out.println(arr[5]);	// 运行出错 数组越界异常
    
            //修改第1个元素的值
            //此处arr[0]相当于一个int类型的变量
            arr[0] = 100;
            System.out.println("arr数组的第1个元素:" + arr[0]);
        }
    }
    
二维数组的使用
  • 静态初始化

    int[][] arr = {{1,2,3},{4,5,6},{7,8,9,10}};//声明与初始化必须在一句完成
    
    int[][] arr = new int[][] {{3,8,2}, {2,7}, {9,0,1,6}};
    

    定义一个名称为arr的二维数组,arr中有三个一维数组,且每个一维数组中的具体元素也都已初始化。

    第一个一维数组:arr[0] = {3,8,2};

    第一个一维数组:arr[1] = {2,7};

    第一个一维数组:arr[2] = {9,0,1,6};

    注意:

    • 不要求二维数组中的每个一维数组长度一致

    • arr.length 不是二维数组中元素的个数,而是二维数组中一维数组的个数

    • arr[i].length 是二维数组中第i个一维数组的长度

  • 动态初始化

    int[][] arr = new int[3][2];	// 二维数组中有三个一维数组 每个一维数组中有两个元素 初始化值为0
    
    int[][] arr = new int[3][];		// 每个一维数组初始化值为 null
    // 可以对这三个一维数组分别初始化
    arr[0] = new int[3]; arr[1] = new int[1]; arr[2] = new int[2];
    
    int[][] arr = new int[][3];		// 错误
    
  • 使用演示

    public class Main {
        public static void main(String[] args) {
            int[][] arr = new int[][] {{3,8,2}, {2,7}, {9,0,1,6}};
    
            System.out.println("arr数组的长度:" + arr.length);       // 3 一维数组的个数
            System.out.println("arr[1]的长度:" + arr[1].length);     // 2 第二个一维数组的长度
            System.out.println("arr[2]中的第3个元素:" + arr[2][2]);
    
            // 修改第一个一维数组中第二个元素的值
            arr[0][1] = 100;
            System.out.println("arr[0]中的第二个元素:" + arr[0][1]);   
        }
    }
    
  • 注意特殊写法情况

    int[] arr[];	// 正确 arr是一个二维数组
    int[] x, arr[];	// 正确 x是一个一维数组 arr是一个二维数组
    
    int arr[][];	// 正确
    

数组的内存分析

内存是用于暂存 CPU 中的运算数据,以及与硬盘等外部存储设备交换的数据。

JVM的内存划分

Java 虚拟机要运行程序,必须对内存空间进行分配和管理。为了提高效率,就对空间进行了不同区域的划分,每一片区域都有特定的处理数据的方式和内存管理的方式。

区域名称 作用
程序计数器 程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址
本地方法栈 当程序中调用了native的本地方法时,本地方法执行期间的内存区域
方法区 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
堆内存 存储对象(包括数组对象),new来创建的,都存储在堆内存。
虚拟机栈 用于存储正在执行的每个Java方法的局部变量表等。
局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放。
一维数组在内存中的存储
public class Main {
    public static void main(String[] args) {
        int[] arr = new int[3];
        System.out.println(arr);// [I@1b6d3586
        System.out.println(arr[0]);// 0
    }
}

上面程序执行流程

  1. 程序执行时,JVM会找到类中的main方法,main方法进入方法栈执行。
  2. 执行int[] arr = new int[3];创建数组时,JVM会在堆内存中开辟出一片连续的空间,存储该数组。
  3. JVM将数组的首地址返回给引用变量arr
二维数据在内存中的存储
public class Main {
    public static void main(String[] args) {
        int[][] arr = new int[3][];
        
        arr[1] = new int[2];

        System.out.println(arr);// [[I@1b6d3586
        System.out.println(arr[0]);// null
    }
}
posted @ 2023-02-06 17:04  msuenb  阅读(368)  评论(0编辑  收藏  举报