java的数组类型

一.数组也是一种类型

  1.         数组是编程语言中最常见的一种数据结构,java中可通过数组元素的索引来访问数组元素,包括为数组元素赋值和取值。
  2.         一旦数组初始化完成,数组在内存总所占的空间将被固定起来,因此数组长度不可变,即使数组中没有存放数据元素,但他的空间任然被保留下来,仍然属于数组。
  3.         java的数组既可以存储基本数据类型,也可以存储引用数据类型,它本身也是一种引用数据类型。例如,   int   是一个基本数据类型,但   int[]   就是一中引用类型了。

二.定义数组

     java语言支持两种语法格式来定义数组

type[] arrayName;
type arrayName[];

通常建议使用第一种方式来定义数组。很容易理解这是一个变量,其中变量名是arrayName,而变量类型是type[]。

注意:定义数组时不能指定数组的长度

三.数组的初始化

java语言中数组必须先初始化,然后才可以使用。所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组袁术赋初值。

数组初始化的方式有两种

  1. 静态初始化:初始化时由程序员显式指定每个数组元素的初值,并由系统决定数组的长度。
  2. 动态初始化:初始化时程序员只能指定数组的长度,由系统为数组元素分配初值。

3.1  静态初始化

语法格式:

arrayName = new type[] {element1,element2,element3...};


但在实际的开发过程中,可以使用简化的方法:
int[] a = {3,5,4,6};

3.2动态初始化

动态初始化只指定数组的长度,由系统为每个数组元素指定初值,其语法格式如下:

arrayName = new type[length];

动态初始化时,系统将按以下规则初始化初值

  1. 当数组元素是基本类型中的整数类型(byte,short,int和long) ,则数组元素的值为0;
  2. 当数组元素是基本类型中的浮点类型(float,double) ,则数组元素的值为0.0;
  3. 当数组元素是基本类型中的字符类型(char) ,则数组元素的值为'\u0000';
  4. 当数组元素是基本类型中的布尔类型(boolean) ,则数组元素的值为false;
  5. 当数组元素是引用类型(类,借口和数组) ,则数组元素的值为null;

四.foreach循环

这种循环遍历数组和集合。使用foreach遍历数组时,无法获得数组的长度,无法根据索引来访问数组,foreach会自动遍历数组中的元素。

其格式如下:

for(type variableName : array|collection){
    //variableName自动迭代访问每个元素。
}


public class ForEachTest
{
    public static void main(String[] args)
    {
        String[] books = {"轻量级java教程",
                            "疯狂java讲义",
                            "疯狂Android讲义"};
       //使用foreach来遍历数组,其中book将自动迭代每个数组元素
        for(String book : books)
        {
            System.out.println(book);
        }
    }
}

五.深入数组

数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存中是分开存放的

5.1内存中的数组

数组引用变量只是一个引用,这个引用变量可以指向任何有效的内存,只有当该引用内存指向有效内存时,才可通过该数组来访问数组元素。

实际的数组对象被存储在堆(heap)内存中,其数组引用变量被存储在栈(stack)中。

数组引用变量是访问堆内存中数组元素的根本方式

如果堆内存中的数组不再有任何引用变量指向自己,则这个数组将会成为垃圾,该数组所占内存将被系统回收。因此,为了让垃圾回收机制回收一个数组所占的内存空间,可以将该数组变量赋为null,切断数组引用变量和实际数组之间的关系。

只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组,这种操作会让人产生数组的长度可变的错觉。

public class ArrayInRam
{
	public static void main(String[] args){
		//定义初始化数组,使用静态初始化
		int[] a = {5,7,20};
		//定义初始化数组,使用动态初始化
		int[] b = new int[4];
		//输出b数组的长度
		System.out.println("b数组的长度为:" + b.length);
		//循环输出a数组的元素
		for(int i=0;i<a.length;i++)
		{
			System.out.println(a[i]);
		}
		//循环输出b数组的元素
		for(int i=0;i<b.length;i++)
		{
			System.out.println(b[i]);
		}
		//因为a是int[] 类型,b也是int[]类型,所以可以将a的值赋给b,也就是让b引用指向a引用指向的数组
		b=a;
		//再次输出b数组的长度
		System.out.println("b数组的长度:" + b.length);
	}
}

对于引用类型变量,系统的引用变量存储中的都是地址。在上面例子中,当执行b=a;时系统将会把a的值赋给b,a和b都是引用类型变量,存储的是地址。因此把a的值赋给b后,就是让b指向a所指向的地址。

5.2基本类型数组的初始化

对于基本类型数组而言,数组元素的值直接存储在对应的数组元素中,因此,初始化数组时,先为该数组分配内存空间,然后直接将数组元素的值存入对应数组元素中。

下面程序定义了一个int[] 类型的数组变量,采用动态初始化的方式初始化了该数组,并显式为每个数组元素赋值。

public class PrimitiveArrayTest
{
	public static void main(String[] args)
	{
		//定义一个int[]类型的数组变量
		int[] iArr;
		//动态初始化该数组,数组长度为5
		iArr = new int[5];
		//采用循环方式为每个数组元素赋值
		for(int i=0;i<iArr.length;i++){
			iArr[i]=i+10;
		}
	}
}

 

上面代码执行第一行代码  int[] iArr;时,仅定义一个数组变量,此时内存中的存储示意图如图4.5所示。

执行了int[] iArr;后,仅在栈内存中定义了一个空引用。这个引用并未指向任何有效的内存,当然也无法指定数组的长度。

当执行了iArr=new int[5];动态初始化后,系统将负责为该数组分配内存空间,并分配默认的初识值:所有元素都被赋值为0,此时内存中的存储示意图如图4.6所示。

 

 

 

 

 

 

 

 

5.3引用类型数组的初始化

引用类型数组的数组元素是引用,因此情况更加复杂。每个数组元素里存储的还是引用,它指向另一块内存,这块内存里存储了有效数据。

class Person
{
	public int age;
	public double height;
	public void info(){
		System.out.println("我的年龄是" + age+"我的身高是"+height);
	}
}

public class ReferenceArrayTest
{
	public static void main(String[] args){
		//定义一个Person[] 类型的名为students的数组变量
		Person[] students;
		//执行动态初始化
		students=new Person[2];
		//创建一个Person实例,并将这个Person实例赋给zhang变量
		Person zhang=new Person();
		//为zhang所引用的Person对象的age,height赋值。
		zhang.age=15;
		zhang.height=158;
		//创建一个Person实例,并将这个Person实例赋值给lee变量
		Person lee = new Person();
		lee.age=16;
		lee.height=161;
		//将zhang变量的值赋给第一个数组元素
		students[0]=zhang;
		//将lee变量的值赋给第二个数组元素
		students[1]=lee;
		//下面两行代码的结果完全一样,因为lee和students[1]指向的是同一个Person实例
		lee.info();
		students[1].info();
	}
}

上面代码的执行过程代表了引用类型数组初始化的典型过程。

执行Person[] students;代码时,这行代码仅在栈内存中定义了一个引用变量,也就是一个指针,这个指针并未指向任何有效的内存区,此时的内存中存储示意图如图4.8所示.

直到执行初始化,本程序对students数组执行动态初始化,动态初始化由系统为每个数组元素分配默认的初识值:null.执行动态初始化以后内存的存储示意图如图4.9所示.

接着代码定义了zhang和lee两个Person实例,定义这两个实例实际上分配了4块内存,在栈内存中存储了zhang和lee两个引用变量,还在堆内存中存储了两个Person实例.此时内存示例图如图4.10所示.

直到程序依次将zhang和lee分别赋给students的两个元素,students数组的两个数组元素将会指向有效的内存区,此时的内存存储示意图如图4.11所示.

此时,zhang和students[0]指向同一个内存区,而且他们都是引用类型变量,因此通过zhang和students[0]来访问Person实例的实例变量和方法的效果完全一样,不论修改students[0]所指向的Person实例的实例变量,还是修改zhang变量所指向的Person实例的实例变量,所修改的是同一个内存区,所以必然相互影响.同理,lee和students[1]是一样的.

 

 

 

 

5.4没有多维数组

java语言中提供了支持多维数组的语法,但是如果从java的数组的底层的运行机制上来说,没有多维数组.

java语言里的数组类型是引用类型,因此数组变量实际上是一个引用,这个引用指向真实的数组内存.数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组.

回到前面定义数组类型的语法:type[] arrName;,这是典型的一维数组的定义语法,如果希望数组元素也是一个引用,而且是指向int数组的引用,则可以把type改为int[] ,那么上面定义数组的语法就是int[][] arrName.

如果把int这个类型1扩大到Java的所有类型(不包括数组类型),则出现了定义二维数组的语法:

type[][] arrayName;

java采用上面的语法格式来定义二维数组,但他的本质还是一维数组,只是其数组元素也是引用,数组元素里保存的引用指向一维数组.

接着对这个"二维数组"执行初始化,同样可以把这个数组当成一维数组来初始化,把这个"二维数组"当成一个一维数组,其元素类型是type[] 类型,则可以采用如下语法来进行初始化:

arrName = new type[length][];

上面的初始化语法相当于初始化了一个一维数组,这个一维数组的长度是length.同样,因为这个一维数组的的数组元素是引用类型的,所以系统为每个数组元素都分配了初识值:null.

使用new type[length][]初始化这个数组后,相当于定义了length个type[]类型的变量,当然,这些type[]类型的变量都是数组类型,因此必须再次初始化这些数组.

下面程序示范了如何把二维数组当成一维数组来处理.

public class TwoDimensionTest
{
	public static void main(String[] args)
	{
		// 定义一个二维数组
		int[][] a;
		// 把a当成一维数组进行初始化,初始化a是一个长度为4的数组
		// a数组的数组元素又是引用类型
		a = new int[4][];
		// 把a数组当成一维数组,遍历a数组的每个数组元素
		for (int i = 0 , len = a.length; i < len ; i++ )
		{
			System.out.println(a[i]);
		}
		// 初始化a数组的第一个元素
		a[0] = new int[2];
		// 访问a数组的第一个元素所指数组的第二个元素
		a[0][1] = 6;
		// a数组的第一个元素是一个一维数组,遍历这个一维数组
		for (int i = 0 , len = a[0].length ; i < len ; i ++ )
		{
			System.out.println(a[0][i]);
		}

		// 同时初始化二维数组的2个维数
		int[][] b = new int[3][4];

		// 使用静态初始化的语法来初始化一个二维数组
		String[][] str1 = new String[][]{new String[3]
			, new String[]{"hello"}};
		// 使用简化的静态初始化语法来初始化二维数组
		String[][] str2 = {new String[3]
			, new String[]{"hello"}};
		System.out.println(str1[1][0]);
		System.out.println(str2[1][0]);
	}
}

由上可知,二维数组是一维数组,其数组元素是一维数组;三维数组也是一维数组,其数组元素是二维数组.....从这个角度来看,java语言里没有多维数组.

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值