【Java】Java数组类型

1.一维数组

1.1.一维数组的声明

在Java中,数组属于引用数据类型,并且也属于一种对象,所以需要使用new创建对象

动态数组初始化

在Java中,动态初始化方式有两种,但是这两种没有本质的区别

1. 数据类型[] 数组名 = new 数据类型[元素个数]
2. 数据类型 数组名[] = new 数据类型[元素个数]

// 动态数组初始化只会为数组开辟对应的空间

需要注意的是,与C/C++语言不同,赋值符左侧的括号中不给元素个数,而在赋值符右侧的括号中给元素个数,并且需要满足赋值符左右两边的数据类型相同

 // 动态初始化数组
 int arr[] = new int[5];// 声明int类型数组arr
 String arr1[] = new String[5];// 声明String类型数组arr1
静态数组的初始化:

静态初始化的方式也有两种:

 1. 数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3, 元素4, ...}
 2. 数据类型 数组名[] = new 数据类型[]{元素1, 元素2, 元素3, 元素4, ...}
 ​
 // 赋值符右侧的括号中可以不写元素个数
 // 静态初始化会在开辟空间时存入提供的数据

但是上面的方法在数组元素过多时会显得冗长,所以可以简写成下面的形式

 1. 数据类型[] 数组名 = {元素1, 元素2, 元素3, 元素4, ...}
 2. 数据类型 数组名[] = {元素1, 元素2, 元素3, 元素4, ...}

尽管可以简写,但是本质还是第一种中的两种方式

 // 静态初始化数组
 int arr2[] = {1, 2, 3, 4, 5};
 String arr3[] = {"字符串1", "字符串2"};

1.2.一维数组的访问

数组长度

在Java中,需要获取数组的长度可以使用数组的length属性

 package com.epsda.array;
 ​
 /**
  * ClassName: test_array
  * Package: com.epsda.array
  * Description:
  *
  * @author lza
  * @version v1.0
  */
 public class test_array {
     public static void main(String[] args) {
         int arr[] = new int[5];
         int length = arr.length;
         System.out.println("length = " + length);
     }
 }
 ​
 输出结果:
 length = 5

注意,在Java中,数组的长度是数组的属性,而不是方法,不同于C/C++中的容器长度是size()

数组的遍历操作:
public class test_array {
     public static void main(String[] args) {
         int arr[] = new int[5];
 ​
         // 插入数据
         for (int i = 0; i < arr.length; i++) {
             arr[i] = i;// 插入数据
             System.out.print(arr[i] + " ");
         }
     }
 }
 ​
 输出结果:
 0 1 2 3 4
数组中的默认值:

在Java中,如果数组开辟了空间,但是并没有放入实际值,那么Java会根据对应的数据类型提供默认值,根据数据类型,有以下默认值:

  1. int/byte/short:默认值为0

  2. double/float:默认值为0.0

  3. char'\u0000'(代表空白字符,其整型值为0)

  4. 引用数据类型:null

  5. 布尔类型:false

数组中的两个常见异常:

1.越界访问异常ArrayIndexOutOfBoundsException

越界访问异常出现在数组的索引超出合法界限

 public class Test_array {
     public static void main(String[] args) {
         int[] arr = new int[3];
         arr[0] = 100;
         arr[1] = 200;
         arr[2] = 300;
         //arr[3] = 400;// 索引3不再数组合法下标范围内
 ​
         //arr[-1] = 1000;// 索引-1不再数组合法下标范围内
 ​
         for (int i = 0; i <= arr.length; i++) {
             System.out.println(arr[i]);// 索引3不再数组合法下标范围内
         }
     }
 }
 ​
 报错结果:
 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
     at com.epsda.array.test_array.main(test_array.java:12)
2.空指针异常NullPointerException

空指针异常一般出现在数组名为null,但是调用了其属性或者方法

public class Test_array {
    public static void main(String[] args) {
        int[] arr = new int[3];
        arr = null;// 将数组名改为null
        System.out.println(arr.length);// 数组名指向不存在的地址,但是访问了length属性
    }
}
 
报错结果:
Exception in thread "main" java.lang.NullPointerException
	at com.epsda.array.test_array.main(test_array.java:5)

2.Java中的内存划分

在Java中,一共有五种内存

  1. 栈(Stack):Java中的方法在运行时都会进栈,也称栈帧空间

  2. 堆(Heap):每次使用new创建对象,都会在堆内存中开辟空间,并为此空间自动分配一个地址值。堆中的数据根据对应的类型都有对应的默认值

  3. 方法区(Method Area):代码暂存区,记录了类的信息以及方法的信息,在方法加载到内存之前,会先将方法和类放置在方法区

  4. 本地方法栈:专门运行native方法,本地方法为对Java功能的扩充

  5. 寄存器。

2.1一维数组的内存分析

同C/C++中一样,在Java中,数组名代表数组的地址


public class test_array {
    public static void main(String[] args) {
        int arr[] = new int[5];
        System.out.println("arr = " + arr);
        }
    }
}
 
输出结果:
arr = [I@154617c

根据前面的Java内存划分,可以分析数组在内存中的结构,以下面的代码为例:


public class test_array {
    public static void main(String[] args) {
        // 动态初始化
        int arr[] = new int[5];
        // 尽管没有存入数据,但是有空间和默认值
        System.out.println("arr.length = " + arr.length);
        // 插入数据
        for (int i = 0; i < arr.length; i++) {
            arr[i] = i;
            System.out.print(arr[i] + " ");
        }
    }
}

内存中如下:

首先编译为.class文件后放入方法区等待方法加载到栈上

接着执行栈上的方法:

赋值之后为:

同样可以推广到多个数组占用不同空间的情况以及两个数组名指向同一块空间的情况

所以Java中的一维数组可以理解为下面的C语言代码

#include <stdio.h>
 
int main()
{
    // 动态初始化数组
    int* arr = (int*)malloc(sizeof(int) * 5);
    // 对应int[] arr = new int[5]
    return 0;
}

3.二维数组

二维数组的声明:

在Java中,二维数组同一维数组一样,使用new关键字创建数组对象

动态初始化:
1. 数据类型[][] 变量名 = new 数据类型[二维数组长度][每一个一维数组长度]
2. 数据类型 变量名[][] = new 数据类型[二维数组长度][每一个一维数组长度]
    
// 也可以写成下面的形式,但是不够美观
数据类型[] 变量名[] = new 数据类型[二维数组长度][每一个一维数组长度]

注意,如果动态初始化一个二维数组时,没有给每一个一维数组长度值,那么此时在堆上只会开辟一个二维数组,而不会在二维数组的空间内开辟一维数组,因为一维数组的长度不确定

如果给定了每一个一维数组长度,那么这个二维数组和C语言的二维数组相同,类似于一张整齐的表格,但是注意C语言的普通二维数组是开辟在栈空间的

静态初始化:
1. 数据类型[][] 变量名 = new 数据类型[][]{{元素1,元素2,...}, {元素1,元素2,...}, {元素1,元素2,...}}
2. 数据类型 变量名[][] = new 数据类型[][]{{元素1,元素2,...}, {元素1,元素2,...}, {元素1,元素2,...}}

同样可以简写为:

1. 数据类型[][] 变量名 = {{元素1,元素2,...}, {元素1,元素2,...}, {元素1,元素2,...}}
2. 数据类型 变量名[][] = {{元素1,元素2,...}, {元素1,元素2,...}, {元素1,元素2,...}}

静态初始化是根据一维数组个数和一维数组元素个数推演出二维数组的长度,所以每一个一维数组长度可以不同,类似于C语言中使用动态内存函数开辟的模拟二维数组,例如下面的C语言代码

#include <stdio.h>
 
int main()
{
 // 定义二维数组的长度,二维数组中每一个元素为int*类型
 int* arr = (int*)malloc(sizeof(int*)*元素个数);
 // 定义每一个一维数组的长度,一维数组中每一个元素为int类型
 arr[0] = int(*)malloc(sizeof(int)*元素个数);
 arr[1] = int(*)malloc(sizeof(int)*元素个数);
 arr[2] = int(*)malloc(sizeof(int)*元素个数);
 //...
 return 0;
}

3.2二维数组的访问

二维数组的访问与一维数组基本一致


public class test_array {
    public static void main(String[] args) {
		// 静态初始化
        int arr[][] = {{1, 2, 3}, {1, 2}, {1, 2, 3, 4, 5}};
        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();
        }
    }
}
 
输出结果:
1 2 3 
1 2 
1 2 3 4 5

3.3二维数组的内存分析

同样可以分析出二维数组在内存上的结构:


public class test_array {
    public static void main(String[] args) {
		// 静态初始化
        int arr[][] = {{1, 2, 3}, {1, 2}, {1, 2, 3, 4, 5}};
        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();
        }
    }
}

类比C语言:

#include <stdio.h>
 
int main()
{
    // 定义二维数组的长度,二维数组中每一个元素为int*类型
    int* arr = (int*)malloc(sizeof(int*)*3);
    // 定义每一个一维数组的长度,一维数组中每一个元素为int类型
    arr[0] = int(*)malloc(sizeof(int)*3);
    arr[1] = int(*)malloc(sizeof(int)*2);
    arr[2] = int(*)malloc(sizeof(int)*5);
    
    // 上面的代码相当于int arr[][] = new arr[3][]
    // arr[0] = new int[3]
    // arr[0] = new int[2]
    // arr[0] = new int[5]
    return 0;
}

要在CentOS 7中的单用户模式修改密码,您可以按照以下步骤操作: 1. 首先,重启系统并进入GRUB引导菜单。您可以按下计算机的电源按钮并立即按下并持续按住Shift键,直到出现GRUB菜单为止。 2. 使用方向键选择第一个启动项,并按下e键进行编辑。 3. 找到以"linux16"开头的那一行,然后去掉其中的"rhgb"和"quiet"参数。在"UTF-8"之后添加"init=/bin/sh"参数。这将让系统在单用户模式下启动并进入一个shell提示符。 4. 按下Ctrl + x键启动修改。 5. 您现在将进入一个单用户模式的shell提示符。输入以下命令以重新挂载根文件系统为可写模式: ``` mount -o remount,rw / ``` 6. 输入以下命令以更改root用户的密码: ``` passwd ``` 7. 按照提示输入新密码并确认。 8. 输入以下命令以重新挂载根文件系统为只读模式: ``` mount -o remount,ro / ``` 9. 输入以下命令以重启系统: ``` reboot ``` 10. 系统将重新启动并返回到正常的登录界面。 请注意,这些步骤将使您能够在CentOS 7中的单用户模式修改root用户的密码。确保您按照指示操作,并确保保护好您的密码以确保系统的安全性。 [参考文献] 提供了在GRUB引导菜单中编辑启动项的具体步骤。 提供了在单用户模式下重新挂载根文件系统为可写模式和只读模式的命令。 提供了在系统中使用命令"reboot"来重启系统的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北海有初拥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值