Java 基础之(十一)一维数组
2016-07-24 21:13
253 查看
说明
数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
数组也是一种数据类型,它本身是一种引用类型。
Java的数组要求所有的数组元素具有相同的数据类型,包括基本数据类型和引用数据类型。一旦数组的初始化完成,数组在内存中所占的空间也被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据全部清空,但它所占的空间依然被保留,依然属于该数组,该数组的长度依然不变。
注意:定义数组时不能定义数组长度。
静态初始化
例如:
也可简化为如下格式:
动态初始化
动态初始化只指定数组的长度,由系统为每个数组元素指定初始值。语法格式如下:
例如:
Java语言的数组索引是从0开始的,最后一个数组元素的索引值数组长度减一。
使用length属性可以访问到数组的长度,一旦获得了数组的长度就可以通过循环来遍历该数组的每个数组元素。举个简单例子:
执行上面代码将输出5个0,因为intArray数组执行的是默认初始化,数组元素是int类型,系统为int类型的数组元素赋值为0;
foreach循环是输出数组元素的一种较为方便的方法。但是若想以数组形式输出数组元素则可使用以下方法:
如果需要访问堆内存中的数组元素,则程序只能通过p[index]的形式实现。也就是说,数组引用变量是访问堆内存中数组元素的根本方式。如果堆内存中数组不再有任何引用变量指向自己,则这个数组将成为垃圾,该数组所占的内存将被系统得垃圾回收机制回收。
从结果来看b数组的长度似乎发生了变化,但是需要记住:
定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。
下面的示意图说明了上面程序的运行过程:
当程序定义并初始化了a、b两个数组后,系统内存中实际产生了4块内存区,其中栈内存中有两个引用变量:a和b;堆内存中也有两块内存区,分别用于存储a和b引用所指向的数组本身。
从图中可以看出a变量所引用的数组长度是3,b变量所引用的数组长度是4。当执行b=a时,系统将会把a的值赋给b,a和b都是引用类型变量,存储的是地址。因此把a的值赋给b后,就是让b指向a所指向的地址。此时计算机内存的存储示意图如下:
从图中可以看出,当执行了b=a之后,堆内存中的第一个数组具有了a、b两个引用。此时第二个数组失去了引用,则将被系统回收,但它的长度不会变,直到它彻底消失。
动态初始化数组后的存储示意图如下所示:
显式指定每个数组元素值后的存储示意图如下所示:
动态初始化studentss数组后的内存存储示意图:
创建两个Person实例后的存储示意图:
此时students数组的两个数组元素依然为null,直到程序依次将zhang、lee赋给students数组的两个数组元素,此时这两个数组元素将指向有效的内存区。为数组元素赋值后的内存存储示意图:
此时,从图中可以看出,zhang和students[0]指向的是同一个内存区。
数组是编程语言中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取出数组元素的值。
数组也是一种数据类型,它本身是一种引用类型。
Java的数组要求所有的数组元素具有相同的数据类型,包括基本数据类型和引用数据类型。一旦数组的初始化完成,数组在内存中所占的空间也被固定下来,因此数组的长度将不可改变。即使把某个数组元素的数据全部清空,但它所占的空间依然被保留,依然属于该数组,该数组的长度依然不变。
定义数组
type[] arrayName;
注意:定义数组时不能定义数组长度。
数组的初始化
Java中数组必须先初始化,然后才可以使用。初始化就是为数组元素分配内存空间,并为每个数组元素赋初始值。静态初始化
arrayName = new Type[]{element1,element2,element3,element4...};
例如:
int[] intArray; intArray = new int[]{5,6,8,10};
也可简化为如下格式:
int[] intArray = {5,6,8,10};
动态初始化
动态初始化只指定数组的长度,由系统为每个数组元素指定初始值。语法格式如下:
arrayName = new type[length];
例如:
int[] intArray = new int[5];
使用数组
数组最常用的用法就是访问数组元素,包括为数组元素赋值和取出数组元素的值。Java语言的数组索引是从0开始的,最后一个数组元素的索引值数组长度减一。
//输出int数组的第三个元素,将输出整数8 System.out.println(intArray[2]); //为int数组的第一个数组赋值 intArray[0] = 1;
使用length属性可以访问到数组的长度,一旦获得了数组的长度就可以通过循环来遍历该数组的每个数组元素。举个简单例子:
int[] intArray = new int[5]; for(int i = 0;i<intArray.length;i++){ System.out.println(intArray[i]); }
执行上面代码将输出5个0,因为intArray数组执行的是默认初始化,数组元素是int类型,系统为int类型的数组元素赋值为0;
foreach循环(输出数组元素方法)
foreach循环遍历数组和集合。使用foreach遍历数组和集合时,无需获得数组和集合的长度,无需根据索引来访问数组元素和集合元素,foreach循环自动遍历数组和集合的每个元素。用法如下:public class TestOne { public static void main(String[] args){ int[] intArray = {2,5,8,4,6}; //使用foreach循环来遍历数组元素,其中i会自动迭代每个数组元素 for(int i:intArray){ System.out.print(" "+i); } } }
输出结果: 2 5 8 4 6
foreach循环是输出数组元素的一种较为方便的方法。但是若想以数组形式输出数组元素则可使用以下方法:
public class TestOne { public static void main(String[] args){ int[] intArray = {1,5,3,4,8,10}; String arr = Arrays.toString(intArray); System.out.print(arr); } }
输出结果: [1, 5, 3, 4, 8, 10]
内存中的数组
因为数组变量是引用类型变量,实际的数组对象存放在堆内存中,如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈内存中。数组在内存中的存储如图所示:如果需要访问堆内存中的数组元素,则程序只能通过p[index]的形式实现。也就是说,数组引用变量是访问堆内存中数组元素的根本方式。如果堆内存中数组不再有任何引用变量指向自己,则这个数组将成为垃圾,该数组所占的内存将被系统得垃圾回收机制回收。
public class TestOne { public static void main(String[] args){ //定义并初始化数组,使用静态初始化 int[] a = {2,5,8}; //定义并初始化数组,使用动态初始化 int[] b = new int[4]; System.out.println("b数组的长度为:"+b.length); for(int i:a){ System.out.println(" "+i); } for(int j = 0;j<b.length;j++){ System.out.println(b[j]); } //因为a是int[]类型,b是int[]类型,所以可将a赋给b //也就是让b引用指向a引用指向的地址 b = a; System.out.println("b数组的长度为:"+b.length); } }
输出结果: b数组的长度为:4 2 5 8 0 0 0 0 b数组的长度为:3
从结果来看b数组的长度似乎发生了变化,但是需要记住:
定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。
下面的示意图说明了上面程序的运行过程:
当程序定义并初始化了a、b两个数组后,系统内存中实际产生了4块内存区,其中栈内存中有两个引用变量:a和b;堆内存中也有两块内存区,分别用于存储a和b引用所指向的数组本身。
从图中可以看出a变量所引用的数组长度是3,b变量所引用的数组长度是4。当执行b=a时,系统将会把a的值赋给b,a和b都是引用类型变量,存储的是地址。因此把a的值赋给b后,就是让b指向a所指向的地址。此时计算机内存的存储示意图如下:
从图中可以看出,当执行了b=a之后,堆内存中的第一个数组具有了a、b两个引用。此时第二个数组失去了引用,则将被系统回收,但它的长度不会变,直到它彻底消失。
基本类型数组的初始化
对于基本数据类型而言,数组元素的值直接存储在对应的数组元素中,因此初始化数组时,先为数组分配内存空间,然后直接将数组元素的值存入对应的数组元素中。例如:public class TestOne { public static void main(String[] args){ //动态初始化数组,数组长度为6 int[] a = new int[6]; for(int i = 0;i<a.length;i++){ a[i] = i+10; System.out.println(a[i]); } } }
动态初始化数组后的存储示意图如下所示:
显式指定每个数组元素值后的存储示意图如下所示:
引用类型数组的初始化
引用类型数组的数组元素是引用。每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效数据。看下面的例子:public class Person { public int age; public double height; void info(){ System.out.println("My age is "+ age+",my height is "+height); } }
public class TestOne { public static void main(String[] args){ //定义一个students数组变量,其类型是Person[];并执行动态初始化 Person[] students = new Person[2]; //创建一个Person对象 Person zhang = new Person(); //为zhang所引用的Person对象的age、height赋值 zhang.age = 15; zhang.height = 158.0; //创建一个Person对象 Person lee = new Person(); //为lee所引用的Person对象的age、height赋值 lee.age = 16; lee.height = 161.0; //将zhang变量的值赋给第一个数组元素 students[0] = p1; //将lee变量的值赋给第二个数组元素 students[1] = p2; //下面两行代码输出结果一样,因为student[0]和zhang指向的是同一个Person实例 students[0].info(); lee.info(); } }
输出结果: My age is 10,my height is 172.0 My age is 20,my height is 180.0
动态初始化studentss数组后的内存存储示意图:
创建两个Person实例后的存储示意图:
此时students数组的两个数组元素依然为null,直到程序依次将zhang、lee赋给students数组的两个数组元素,此时这两个数组元素将指向有效的内存区。为数组元素赋值后的内存存储示意图:
此时,从图中可以看出,zhang和students[0]指向的是同一个内存区。
相关文章推荐
- HashMap的实现原理
- Java源码-简单手绘程序
- JAVA实现观察者模式
- Struts2数据传输的背后机制
- java多线程--condition条件
- Java 读取配置文件中的信息 中文乱码
- JavaServlet实现文件上传
- Java虚拟机知识整理——类加载的过程
- java学习之路 之 基本语法-程序流程控制-循环结构-嵌套循环练习题
- 深入理解Spring4框架(二)——容器
- java学习之路 之 基本语法-程序流程控制-循环结构-for 循环练习题
- myeclipse关联weblogic时提示 D:\program\weblogic is not a valid BEA WebLogic Server v10.x installation directory
- SpringMVC处理请求流程(转载)
- 【java基础】JAVA常用正则表达式
- JAVA实现单例模式
- Java 不用数组打印杨辉三角
- 坦克大战_我方坦克发射子弹
- Java Exchange企业邮件服务器 发Email
- Java方法的值传递机制
- eclipse添加安卓源码