【Java知识课堂】数组详细介绍(一)

简介: 【Java知识课堂】数组详细介绍

1、数组的基本概念


1.1为什么要使用数组

       如果我们要定义三个整型变量并赋值,我们可以一个一个写,但是如果我们要定义10个或100个变量呢?我们如果再一个一个定义就会显得过于麻烦,也会让代码显的冗余!

而如果我们想定义一组数据,同时这组数据都是相同数据类型的,那我们就可以用“数组”来定义这书数据

1.2什么是数组

数组:可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。

  1. 数组中存放的元素类型形同
  2. 数组的空间是连在一起的
  3. 每个空间有自己的编号,起始位置的编号为0,即数组的下标

1.3数组的创建及初始化

1.3.1 数组的创建和介绍

int[] array = new int[5];
组成 int int[ ] array new 5

含义

表示数组中存放的元素的类型为整数型 表示数组的类型为整数型  数组的名字 创建对象关键字

表示数组的长度

“array”是一个变量,其中存储的是数组的地址

其中 '[' 表示数组类型,'I' 表示整数,'14ae5a5' 是地址的哈希值,也可以理解为地址。


在Java中,我们对于这种存储地址的变量,通常称为 “引用变量”【引用】


而‘new’是创建对象的关键字,所以我们创建的数组也是‘对象’!(这就和C语言中数字区分开了,Java中的数组其实就是对象)


所以,在引用变量当中,存储了对象的地址,一般叫做这个引用/指向了一个对象。

1.3.2 数组的初始化

数组的初始化主要分为动态初始化和静态初始化

1.动态初始化:在创建数组时,直接指定数组中元素的个数

int[] array = new int[5];

2. 静态初始化:在创建数组时,不直接指定数据元素个数,而直接将具体的数据内容进行指定

int[] array1 = new int[]{1,2,3,4,5,6,7,8};
double[] array2 = new double[]{1.0,2.0,3.0,4.0,5.0};
String[] array3 = new String[]{"hello","world"};
  • 静态初始化虽然没有指定数组长度,但编译器在编译时,会根据{}中元素个数来确定数组的长度。
  • 静态初始化时,{}中数据必须与 [ ] 前的数据类型一样。
  • 静态初始化可以简写,省去new T[]

例如:

int[] array1 = {1,2,3,4,5,6,7,8};
    double[] array2 = {1.0,2.0,3.0,4.0,5.0};
    String[] array3 = {"hello","world"};

(注意:虽然省去了new T[ ],但是编译器编译代码时还是会还原)

如果不确定数组当中内容时,使用动态初始化,否则建议使用静态初始化。

静态和动态初始化也可以分为两步,但是省略格式不可以

 

//动态初始化
    int[] array1;
    array1 = new int[10];
    //静态初始化
    int[] array2;
    array2 = new int[]{1,2,3,4};

注意:省略格式不可以拆分,否则编译失败

7ad240d8d64da339e6bfd1546b6c21c7_88bafd64212d4088bd4b48c90b9fd468.png

如果没有对数组进行初始化,数组中元素被这设置为默认值

        1、如果数组中存储的元素为基类类型,默认值为基类类型对于的默认值


类型 默认值
byte 0
short 0
int 0
long 0
float 0.0f
double 0.0
char /u0000
boolean false

       2、如果数组中存储元素类型为引用类型,默认值为null


1.4数组的使用

1.4.1数组中元素访问

       数组在内存中是一段连续的空间,空间的编号都是从0开始的,依次递增,该编号称为数组的下标。


       数组可以通过下标访问数组中任意位置的元素,同时还能通过 [ ] 对数组中的元素进行修改!

int[] array = new int[]{1,2,3,4,5};
    System.out.println(array[0]);
    System.out.println(array[1]);
    System.out.println(array[2]);
    array[2] = 30;
    System.out.println(array[2]);

159c4d2a30a4274da279ac64d85417d5_77e7ab4091ec4b8b822d67d0bd38c6a5.png

【注意事项】


数组是一段连续的内存空间,因此支持随机访问,即通过下标快速访问数组中任意位置的元素

下标从0开始,介于[0,N) 之间不包含N,N为元素个数,数组访问不能越界,否则编译器会报出下标越界异常

c31aa6f5da1af63edf00141e3b6042aa_aa2e0e14fbf44556a9f43bf54a0b3094.png

1.4.2 遍历数组 【3种方式】

什么是“遍历”?  所谓遍历就是指将数组中的所有元素都访问一遍!


例如:

int[] array = {1,2,3,4,5};
    System.out.println(array[0]);
    System.out.println(array[1]);
    System.out.println(array[2]);
    System.out.println(array[3]);
    System.out.println(array[4]);

上述代码虽然可以起到对数组中元素的遍历,但是如果数组中元素增加到100个呢?我们难道要写100条打印语句吗?

第一种遍历方式


为了解决上述问题,用循环来进行遍历打印。

int[] array = {1,2,3,4,5,6,7};
    for (int i = 0; i < 7; i++) {
        System.out.print(array[i]+" ");
    }

1a8d550a27ad1cc5702c0a66fd644d57_6303f089363b4d7f945b77aaa9e7764e.png

现在又有一个问题,如果数组增加了一个元素,那么我就应该把for循环的条件改为“ i < 8”,这样就显得会很麻烦。我们能否直接获取数组的长度呢?


【注意】:在数组中,可以通过 ‘数组对象.length’ 来获取数组的长度

27aa82828b59723497dcb77ccea91a53_c014044b29da40cebcee4406dcfe0dcf.png

第二种遍历方式

同时,也可以使用 for-each 遍历数组

int[] array = {10,20,30,40};
    for(int x:array){
        System.out.print(x+" ");
    }

48b525b39b1d381fa4350c680ae123db_f86551f84e6d4f8da7b5ab124b442295.png

for-each 是 for 循环的另外一种使用方式,能够更方便的完成对数组的遍历,可以避免循环条件和更新语句写错。

第三种遍历方式

在Java中,为了让我们更好的去操作数组,提供了一系列的方法,这些方法在工具类Arrays当中

如下


在使用上述方法时,我们需要到入Arrays的包!

import java.util.Arrays;

如果你不想手动添加,当你在写Arrays时,编译器会提示,按enter键编译器就能直接导入

71acce2e0e299b9095d10f333e6906bc_0330afc906b84b8bb5b280e79a64dd31.png

而toString方法其实就是把我们传入的数组,以字符串的形式进行输出。


我们查看toString源代码就能看出来,返回值为String类型,并且在数组前后加上了‘[’‘]’。

2e03be04d29c761c17e5d101b3ef9dab_7666cc6f106a40f5a2d47b84101bfd88.png



2.数组是引用类型


2.1基本类型变量与引用类型变量的区别

在上文我们提到,引用类型的变量,是对对象的引用,而与基本类型变量最大的不同就是,


基本变量中存储的是本身的值,而引用类型的变量存储的是对象的地址。


基本类型变量:用基本数据类型创建的变量


我们来看下面这个例子:


在讲解下面这个例子之前先扩展两个小知识


虚拟机栈(JVM Stack) : 其中存储的是与方法调用相关的信息,每个方法执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他一些信息,保存的都是与方法执行时相关的一些信息。

堆(Heap): JVM管理的最大内存区域,使用 new 创建的对象都是在堆上保存(例如下面的 new int[]{1,2,3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。

public static void main(String[] args) {
        int a = 10;
        int[] array = new int[]{1,2,3};
    }

在上面代码中,a和array都是main方法内部的变量,其空间都在main方法对应的栈帧都分配


a 是内置类型的变量,因此空间中保存的就是给该变量初始化的值


array 是数组类型的引用变量,其中保存的值是所引用对象在堆中存放的地址

a453e0c9059420d8c284f800eef37195_640dac4758b442bdbe10cc861634ef2e.png

我们可以看到,引用变量并不直接存储对象本身,而是存储对象在堆中所在的地址。通过该地址,引用变量便可以去操作对象。(类似于C语言中的指针)


2.2细讲引用变量

我们来看一下下面这段代码运行的结果

public static void main(String[] args) {
        int[] array1 = new int[3];
        array1[0] = 1;
        array1[1] = 2;
        array1[2] = 3;
        System.out.println("array1 :"+Arrays.toString(array1));
        int[] array2 = new int[]{100,200,3,4,5};
        System.out.println("array2 :"+Arrays.toString(array2));
        array1 = array2;
        array1[2] = 300;
        array1[3] = 400;
        array2[4] = 500;
        System.out.println("array1 :"+Arrays.toString(array1));
    }

19244d691a8b8c7e2fa5bc51e21dc8c1_d4ddecfc79d84244bd07a6b8d350f44f.png

我们不难发现,通过array1所打印出数组变了,也就是说引用变量array1指向的对象变了,同时array2和array1通过下标去对象进行了修改。


下面我通过画图的形式分三步具体讲解这一过程:


第一步:对象的创建


1.创数组array1 ,但是没有给数组元素设置初始值,因此每个位置都是0


2.array1通过下标的方式将数组元素分别修改为1、2、3


3.创建数组array2

4a6da2d85c6746d9402be58e4bcd4b96_9a2d41b6c0b74d9fa33ac8bdfd1fdf17.png


第二步:改变引用对象  array1 = array2

array1 = array2 这段代码的意思是让array1去引用array2 引用的数组空间,也就是说array1和array2可以同时调用同一个数组。此时array1中的地址改变为0x002412


第三步:array1和array2通过下标修改同一个数组对象


array1通过下标将数组2中第三个和第四个元素分别修改为300和400,此时array2也能看到数组中修改后的值,这里是因为array1和array2此时引用的是同一个数组对象!


然后array2通过下标把数组中第五个元素修改为500,此时array1也能看到数组中修改的值。

62026e9540daf32ad80ff70e0686f23e_20da55f2f048404d885f98483687106d.png


通过打印我们能看到最终的结果


2.3 引用变量的空引用

在实际使用中,我们可能只想创建一个引用变量,并不想有所指向。这样我们就可以把null赋值给该引用变量

【引出】 null 在Java中表示“空引用”,也就是不指向对象的引用


public static void main(String[] args) {
         int[] arr = null;
         }

在这里要强调一点,在C语言语言中NULL和0等价的,但是在Java中null就是null跟0没有任何关系比如我们将0赋值给引用变量时就会报错!


【注意】


       null 的作用类似于C语言中的 NULL(空指针),都是表示一个无效的内存位置。因此不能对这个内存进行任何读写操作!


       所以当给引用变量赋值 null 时,该引用变量既不能通过'.'访问length,也不能通过下标进行访问。如果进行以上错误的操作的话,编译器就会报出空指针引用异常警报 ‘NullPointerException’


以下是报错信息截图:

36f6a4f0313fe59222b25ed8b4ed7324_058d134680bd4ce3b5cb7ff49588d343.png

相关文章
|
4天前
|
Java
环形数组链表(java)
环形数组链表(java)
6 0
|
18小时前
|
存储 算法 Java
Java中常用的数组函数及其应用场景
Java中常用的数组函数及其应用场景
|
3天前
|
Java 程序员 容器
五分钟学Java:打印Java数组最优雅的方式是什么?
五分钟学Java:打印Java数组最优雅的方式是什么?
|
4天前
|
机器学习/深度学习 算法 搜索推荐
Java数组(3)
Java数组(3)
21 0
|
4天前
|
存储 Java
Java数组(2)
Java数组(2)
11 0
|
4天前
|
存储 Java 编译器
Java数组(1)
Java数组(1)
10 0
|
4天前
|
Java
数组栈(java)
数组栈(java)
8 0
|
4天前
|
Java
数组链表(java)
数组链表(java)
5 0
|
4天前
|
Java
二维数组与稀疏数组转换(java)
二维数组与稀疏数组转换(java)
6 0
|
5天前
|
Java
java将字符串按照指定长度分割成字符串数组
java将字符串按照指定长度分割成字符串数组
8 0