java数组

Java中的数组是一种数据类型,要求所有元素具有相同类型。数组一旦初始化,长度便不可变。初始化包括静态(指定每个元素初始值)和动态(指定长度,系统分配初始值)两种方式。数组元素可以是基本类型或引用类型,引用类型如对象数组中元素可以是子类实例。内存管理中,数组存储在堆内存,局部变量在栈内存。二维数组本质上是一维数组的数组,初始化时可以先指定行数,后续再初始化列数。Java提供Arrays类方便数组操作,包括静态初始化、排序和设置等方法。
摘要由CSDN通过智能技术生成

数组:首先数组也是一种类型
Java的数组要求所有的数组元素具有相同的数据类型。因此,在 一个数组中,数组元素的类型是唯一的,即一个数组里只能存储一种数据类型的数据,不能存储多种数据类型的数据。
注意: 因为Java语言是面向对象的语言,而类与类之间可以支持继承关系,这样可能产生一个数组里可以存放多种数据类型的假象。例如有一个水果数组,要求每个数组元素都是水果,实际上数组元素 既可以是苹果,也可以是香蕉(苹果、香蕉都继承了水果,都是一 种特殊的水果),但这个数组的数组元素的类型还是唯一的,只能是水果类型。
一旦数组的初始化完成,数组在内存中所占的空间将被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据清空, 但它所占的空间依然被保留,依然属于该数组,数组的长度依然不变。
Java的数组既可以存储基本类型的数据,也可以存储引用类型的数据,只要所有的数组元素具有相同的类型即可。值得指出的是,数组也是一种数据类型,它本身是一种引用类型。例如int是一个基本类型,但int[](这是定义数组的一种方式)就是一种引用类型了。
学生提问:int[]是一种类型吗?怎么使用这种类型呢?
答:没错,int[]就是一种数据类型,与int类型、String类型类似, 一样可以使用该类型来定义变量,也可以使用该类型进行类型转换 等。使用int[]类型来定义变量、进行类型转换时与使用其他普通类 型没有任何区别。int[]类型是一种引用类型,创建int[]类型的对象也就是创建数组,需要使用创建数组的语法。

数组的初始化有如下2种方式。
1.静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。
三种形式来进行静态初始化。
在这里插入图片描述

因为Java语言是面向对象的编程语言,能很好地支持子类和父类的继承关系:子类实例是一种特殊的父类实例。在上面程序中,String类型是Object类型的子类,即字符串是一种特殊的Object实例。
除此之外,静态初始化还有如下简化的语法格式:
在这里插入图片描述

使用上面静态初始化简化语法执行初始化的数组不能使用var定义数组变量。
2.动态初始化:
初始化时程序员只指定数组长度,由系统为数组元素分配初始值。
动态初始化的语法格式如下:
在这里插入图片描述

在上面语法中,需要指定一个int类型的length参数,这个参数指定了数组的长度,也就是可以容纳数组元素的个数。与静态初始化相似的是,此处的type必须与定义数组时使用的type类型相同,或者是定义数组时使用的type类型的子类。下面代码示范了如何进行动态初始化。执行动态初始化时,程序员只需指定数组的长度,即为每个数组元素指定所需的内存空间,系统将负责为这些数组元素分配初始值。

数组指定初始值时,系统按如下规则分配初始值。
1.数组元素的类型是基本类型中的整数类型(byte、short、int和long),则数组元素的值是0。
2.数 组 元 素 的 类 型 是 基 本 类 型 中 的 浮 点 类 型 ( float 、double),则数组元素的值是0.0。
3.数组元素的类型是基本类型中的字符类型(char),则数组元素的值是’\u0000’。
4.数组元素的类型是基本类型中的布尔类型(boolean),则数组元素的值是false。
5.数组元素的类型是引用类型(类、接口和数组),则数组元素的值是null。
注意:
不要同时使用静态初始化和动态初始化,也就是说,不要在进行数组初始化时,既指定数组的长度,也为每个数组元素分配初始值。
在定义数组类型的局部变量时,同样可以使用var来定义变量—只要在定义该变量时为其指定初始值即可,这样编译器就可推断出该变量的类型。

内存
涉及到内存,那就要知道内存是什么?怎么分的?为什么有栈内存和堆内存之分?
答:当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是放在栈内存中的;在程序中创建一个对象时,这个对象将被保 存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(在方法的参数传递时很常见),则这个对象依然不会被销毁。只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。
如果堆内存中数组不再有任何引用变量指向自己,则这个数组将成为垃圾,该数组所占的内存将会被系统的垃圾回收器回收。因此,为了让垃圾回收器回收一个数组所占的内存空间,可以将该数组变量主动赋为null,也就切断了数组引用变量和实际数组之间的引用关系,实
际的数组也就成了垃圾。只要类型相互兼容,就可以让一个数组变量指向另一个实际的数
组,这种操作会让人产生数组的长度可变的错觉。必须牢记:定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。
看待一个数组时,一定要把数组看成两个部分:一部分是数组引用,也就是在代码中定义的数组引用变量;另一部分是实际的数组对象,这部分是在堆内存里运行的,通常无法直接访问它,只能通过数组引用变量来访问。

数据元素类型为基本数据类型/引用类型
数组元素为基本类型没什么可说,数组元素为引用类型只需要记住一个图,回忆场景即可;
在这里插入图片描述

二维数组,实际上是一维数组的一维数组,有点怪异:
语法格式
Int[][] 数组名称 = new int[行数][列数];
Int[][] arr = new int[2][3];
初始化了一个长度为2的一维数组,且元素都是长度为3的数组;数据类型int的2行3列的二维数组;
由于二维数组的本质仍是一个一维数组,所以初始化时也是在初始化一维数组,那么,当不确定“第二维度”的数组元素数量时,在赋值符号右侧,创建数组对象的第二个中括号中可以留空。但是在使用此二维数组前必须对第二维度的数组(留空的括号)进行初始化。不然会出现空指针异常—NullPointerException。
主要记住初始化的时候:int[][] arr = new int[4][],初始化这样写,代表数组的长度是4,即4行,然后再进行列的初始化:arr[0] = new int[3];//初始化“第二维度”的一维数组
arr[0][0] = 1;
arr[0][1] = 2;
arr[0][2] = 3;
arr[1] = new int[2];
相当于:
1.创建了一个名为arr的一维数组 长度为4,arr的第一个元素为数组,长度为3
2.这个数组没有名字 只能通过arr[0]来表示,此数组的三个元素分别是1,2,3
2.arr的第二个元素为数组,长度为2,可以不是3.这个数组没名字,只能通过arr[1]来表示,
此数组的2个元素都为0
3.arr数组的其他元素的值都为null。

所谓的二维数组只需要理解第一步初始化,就明白了全部。
int[][] arr = new int[4][],这一步内存是怎么分布的,则完全明了:
在这里插入图片描述

然后就好理解了。由于a数组的元素必须是int[]数组,所以接下来的程序对a[0]元素执行初始化,也就是让堆内存中的第一个数组元素指向一个有效的数组内存,指向一个长度为2的int数组。因为程序采用动态初始化a[0]数组,因此系统将为a[0]所引用数组的每个元素分配默 认的初始值:0,然后程序显式为a[0]数组的第二个元素赋值为6。此时在内存中的存储示意图
在这里插入图片描述

疑问:
能否让6那里再指向一个数组,成为三维数组?
No,至少本讨论中不行,因为Java是强类型语言,当定义 a数组时,已经确定了a数组的数组元素是int[]类型,则a[0]数组的 数组元素只能是int类型,所以灰色覆盖的数组元素只能存储int类型 的变量。对于其他弱类型语言来说,可以的,如python

但是这样初始化太麻烦了,一步一步的,其实可以同时初始化行和列!!!
Int[][] b = new int[3][4];
在这里插入图片描述

静态初始化也行,太麻烦:
String[][] str1 = new String[][]{new String[3],new String[],{“hello”}};
使用简化的静态初始化语法来初始化二维数组:
String[][] str2 = {new String[3],new String[],{“hello”}};
在这里插入图片描述

数组直接操作麻烦,java提供了Arrays类,包含一些static修饰的方法可以直接操作数组。
具体点api实战中研究使用吧!
Arrays类处于java.util包下,为了在程序中使用Arrays类,必 须在程序中导入java.util.Arrays类。除此以外,在 System类中也有操作数组的static方法:
static void arraycopy(Object src, int srcPos, Object dest, int destPos,int length)方法,该方法可以将src数组里的元素值赋给dest数组的元素,其中srcPos指定从src数组的第几个元素开始赋值,length参数指定将src数组的多少个元素值赋给dest数组的元素。
Java 8增强了Arrays类的功能,为Arrays类增加了一些工具方法,这些工具方法可以充分利用多CPU并行的能力来提高设值、排序的性能。以parallel开头的方法都表示该方法可利用CPU并行的能力来提高性能。
数组适合用来处理同一类型的数据,最典型的demo就是浮点数转换成人民币读法;还有五子棋、连连看、俄罗斯 方块、扫雷等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值