数组
2018-05-31 14:31:37
数组类型
。数组也是一种类型,其本身就是一种引用类型
。Java要求数组中所有元素具有相同的数据类型
。数组一旦初始化完成,数组在内存中所占用的空间固定,因此数组的长度将不可改变,即使把某个数组uansu数据清空,但它所占空间已然被保留
。Java数组存储数据类型既可以是基本类型也可以是引用类型
定义数组
。数组定义语法格式
。。type[] arrayName;
*具有更好的语意和可读性
*type[]作为类型使用(等同于int之类)
。。type arrayName[];
。。定义数组是不能定义数组长度
。。以上只是表示数组的定义,并未指向任何有效的额内存空间,因此还没有内存空间来存储数组元素
。。只有对数组初始化后才可以使用
数组的初始化
。初始化,即为数组元素分配内存空间并给每个数组元素赋初始值
。初始化方式
。。静态初始化
*由程序员显示指定每个数组元素的初始值,由系统决定数组长度
*arrayName=new type[]{element1,element2,element3……};
**type为数组元素的基本类型
**显示指定的数组元素值类型必须与new 关键字后的type类型相同,或其子类实例
。。动态初始化
*程序员指定数组长度,由系统为元素分配初始值
*arrayName=new type[length];
**只需指定数组长度就可以为每个数组元素指定所需的内存空间,系统将会为这些元素分配初始值
***数组元素是整数类型(byte、short、int、long)-0
***数组元素是浮点类型(float、double)-0.0
***数组元素是字符类型(char)-‘\u0000’
***数组元素是布尔类型(boolean)-false
***数组元素是引用类型(类、接口、数组)-null
。实际开发中常数组定义与初始化同时完成
。静态初始化和动态初始化不能同时使用,即不能同时给数组指定长度和给数组元素分配初始值
使用数组
。索引[0-length-1]
。当范文元素是定索引值小于0或大于数组长度时,编译时不会报错,但执行出现数组索引越界异常(java.lang.ArrayIndexOutOfBoundsException):N
数组在内存中的运行机制
内存中的数组
。数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存。只有当该引用指向有效内存后才可通过该数组变量来访问数组元素(类似C++指针)
。引用变量是访问真是对象的根本方式。要访问数组对象本身,则需要通过引用变量来访问
。实际数组对象被存储在堆内存中;如果引用该数组对象的数组引用变量是一个局部变量,则它被存储在栈内存当中。
。。若要访问堆内存当中的数组元素,则通过p[index]形式实现。数组引用变量是访问堆内存中数组元素的根本方式

。若堆内存数组中不再有任何引用变量指向,则该数组将成为垃圾,由系统垃圾回收机制收回
。。为让垃圾回收机制收回一个数组占用的内存空间,可将该数组变量赋为null,切断数组引用变量与实际数组之间的引用关系,实际数组成为垃圾
。实例
。。定义并初始化a、b两个数组后,系统分别产生a、b两块的栈内存及其对应的堆内存
。。a、b引用各自引用的数组对象:a所引用的数组长度为3;b所引用的数组长度为4
。。当执行b=a;时,将a所指向的地址赋给b,即b同样指向a所指向的地址
。。在a、b引用变量都指向了同一个数组对象时,另一个数组对象失去引用,成为垃圾(长度不会改变),直到被回收
。看待数组,要将数组分成两部分
。。数组引用:代码中定义的数组引用变量,如上的a、b
。。实际数组对象:是在堆内存中运行的,通常无法直接访问,只能通过数组引用变量来访问
基本类型数组的初始化
。int[] array;初始化定义,在栈内存当中定义了一个空引用,并没有指向任何有效的内存,无法指定数组长度
。array=new int[4];动态初始化。系统为数组分配内存空间,并分配默认初始值(赋值为0)
。循环为数组赋值,数组元素值成为程序显示指定的值
引用类型数组的初始化
。引用类型数组的数组元素是引用:数组对象本身需要引用变量访问;每个数组元素里存储的还是引用,指向另一块内存,内存里存储了有效数据
。 实例
。。先定义一个Person对象
。。定义Person[]数组,动态初始化Person[]数组,为数组元素指定值
*Person[] students;在栈内存中定义一个引用变量(也就是一个指针),并未指向任何有效内存区
*students=new Person[2];数组动态初始化,数组元素为引用,该引用并未指向任何有效内存,则系统为数组各元素分配默认初始值null。即students数组元素不能被直接使用

*Person zhang=new Person();和Person zhang=new Person();创建了zhang和lee两个实例。在栈内存中为zhang和lee两个引用变量分配两块内存;在堆内存中分别存储两个Person实例。而students数组两个元素值依然为null
*students[0]=zhang; students[1]=lee;将zhang和lee两个引用变量分别赋给students的两个元素:此时引用类型students[0]和zhang指向同一个内存区;students[1]和lee也指向同一个Person对象
多维数组
。Java提供支持多维数组的语法,但从数组底层运行机制来看,根本还是一维数组
。。Java语言里数组类型是引用类型,即数组变量是一个引用并指向真实的数组内存;
。。数组元素类型也可以是引用。如果数组元素引用再次指向真实数组内存,则形式效果为多维数组
。定义
。。一维数组类型定义:type[] arrName; type是数组元素类型
。。如果希望数组元素类型是个引用类型,且是各指向int数组的引用,则type具体为int[](int[]是一种类型),即数组引用类型数组定义为int[][] arrName;
*以上定义等同于type[] arrName;,其中type为int[]
。初始化
。。arrName=new type[length][];
*相当于初始化了一个引用类型(数组类型type[])的一维数组,长度为length,每个数组元素分配初始值为null
*type[]类型的变量是素组类型,需要再次初始化
。实例
。。将二维数组当成一维数组初始化
。。初始化a[0]

。一次性初始化多维数组
。。动态初始化int[][] b=new int[3][4];
*数组变量b指向数组长度为3的数组;被指向的数组元素是指向长度为4的int[]类型的数组,其元素为0
。。静态初始化String[][] str1=new String[][]{new String[3],new String[]{“hello”}};
*简化静态初始化String[][] str2={new String[3],new String{“hello”}};
*String为引用类型
Arrays:Java8增强的工具类
。Arrays类在java.util包下,要使用Arrays类必须导入java.util.Arrays类
。Java提供的Arrays类包含了一些static修饰的方法(static修饰的方法可以直接通过类名直接调用),可以直接操作数组:
。。int binarySearch(type[]a,type key)
*使用二分法查询key在数组a中出现的索引:如果数组不包含key返回负数
*调用该方法时要求数组元素已经按照升序排列
。。int binarySearch(type[]a,int fromIndex,int toIndex,type key)
*与上一个方法类似,要求搜索a数组中从fromIndex到toIndex索引的元素
*调用该方法时要求数组元素已经按照升序排列
。。type[] copyOf(type[] original,int length)
*把original数组复制成一个新的数组
*若length小于数组长度,新数组元素为原数组的前length个元素
*若length大于数组长度。新数组为原数组内容加上0(数组类型)/false(布尔类型)/null(引用类型)
。。type[] copyOfRange(type[] original,int from,int to)
*与上一个方法相似,复制original数组索引从from到to的元素
。。boolean equals(tyoe[] a,type[] a2)
*若数组a与数组a2长度相等且a与a2数元素一一相同,方法将返回true
。。void fill(type[] a,type val)
*将数组元素都赋值val
。。void fill(type[] a,int fromIndex,int toIndex,tpe val)
*将数组索引从fromIndex到toIndex的元素赋值val
。。void sort(type[] a)
*对数组元素进行排序
。。void sort(type[] a,int fromIndex,int toIndex)
*对索引从fromIndex到toIndex的元素进行排序
。。String toString(type[] a)
*将一个数组转换成一个字符串。
*按顺序把多个数组元素连接在一起,多个元素之间使用英文逗号(,)和空格隔开
。实例
数组应用实例
。九九乘法表
。未完待续……

浙公网安备 33010602011771号