Java - Array Initialization

数组:相同类型的、用一个标识符名称封装到一起的,一个对象序列or基本类型数据序列。数组定义方式:int[] a1; 编译器不允许指定上述代码中数组的大小。这就又把我们带回到有关“引用”的问题上。现在拥有的只是对数组的一个引用,而且也没给数组分配任何空间。为了给数组创建相应的存储空间,必须写初始化表达式。 **对于数组,初始化动作可以出现在代码的任何地方,但也可以使用一种特殊的初始化表达式,它必须在创建数组的地方出现。这种特殊的初始化是由一对花括号括起来的值组成的。在这种情况下,存储空间的分配(等价于使用new)将由编译器负责。例如: int[] a1 = {1, 2, 3, 4, 5}; 那么,为什么还要在没有数组的时候定义一个数组引用(int[] a1;)呢?在Java中可以将一个数组赋值给另一个数组,所以可以这样:a2 = a1; 其实真正做的只是复制了一个引用。

/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

public class Arrays {

	public static void main(String[] args) {

		int[] a1 = {1, 2, 3, 4, 5};

		int[] a2 = a1;

		for (int i = 0; i < a2.length; i++) { a2[i]++; }

		for (int i = 0; i < a1.length; i++) { System.out.println(a1[i]); }

	}

}

**如果在编写程序时,并不能确定在数组里需要多少个元素,那么该怎么办呢?可以直接用new在数组里创建元素。尽管创建的是基本类型数组,new依然可以工作(不能用new创建单个的基本类型数据)。

/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

import java.util.Random;

public class ArrayNew {

	public static void main(String[] args) {

		Random rand = new Random();

		int[] a1;

		a1 = new int[rand.nextInt(5)];

		System.out.println("a1.length = " + a1.length);

		for (int i = 0; i < a1.length; i++) { 

			a1[i] = rand.nextInt(100);

			System.out.println("a1[" + i + "] = " + a1[i]);

		}

	}

}
  
  
 
当然,数组也可以在定义的同时进行初始化:int[] a = new int[rand.nextInt(20)]; 如果可能的话,应该尽量这么做。
**如果数组里的元素不是基本数据类型,那么必须使用new。这里再次遇到引用问题,因为所创建的数组里每个元素都是一个引用。
/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

import java.util.Random;

public class ArrayClassObj {

	static Random rand = new Random();

	public static void main(String[] args) {

		Integer[] a1 = new Integer[rand.nextInt(10)];

		System.out.println("a1.length = " + a1.length);

		for (int i = 0; i < a1.length; i++) {

			a1[i] = new Integer(rand.nextInt(1000));

			System.out.println("a1[" + i + "] = " + a1[i]);

		}

	}

}
   
   
 

这里,即便使用new创建数组之后:Integer[] a1 = new Integer[rand.nextInt(10)]; 它还只是一个引用数组,并且直到通过创建新的Integer对象,并把对象赋值给引用,初始化进程才算结束:a1[i] = new Integer(rand.nextInt(1000)); 也可以用花括号括起来的列表来初始化对象数组。有两种形式:

/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

public class ArrayInit {

	public static void main(String[] args) {

		/**

		 * 隐式创建数组对象 

		 */

		Integer[] a = { new Integer(1), new Integer(2), new Integer(3), };

		/**

		 * 显式创建数组对象 

		 */

		Integer[] b = new Integer[] { new Integer(1), new Integer(2), new Integer(3) };

	}

}
  
  
 
第一种形式有时很有用,但由于数组的大小在编译时就决定了,所以很受限制。初始化列表的最后一个逗号是可选的(这一特性使维护长列表变得更容易)。
第二种形式提供了一种方便的语法来创建对象并调用方法,这可以应用于参数个数或类型未知的场合。由于所有的类都直接或间接继承于Object类,所以可以创建以Object数组为参数的方法,并像下面这样调用:
/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

class A { int i; }



public class VarArgs {

	static void print(Object[] obj) {

		for (int i = 0; i < obj.length; i++) System.out.println(obj[i]);

	}

	public static void main(String[] args) {

		print(new Object[] { new Integer(54), new VarArgs(), new Float(4.3), new Double(7.55) });

		print(new Object[] { "one", "two", "three", "four" });

		print(new Object[] { new A(), new A(), new A(), });

	}

}
   
   
 

可以看到print()方法使用Object数组作为参数,然后遍历数组,打印每个对象。标准Java库中的类能输出有意义的内容,**但自己建立的类(A和VarArgs)的对象,打印出的内容只是类的名称以及后面紧跟着的一个@符号,和一个十六进制数字(这个数字代表对象的堆地址)。于是,缺省行为(如果没有定义toString()方法的话)就是打印类的名字和对象的地址。

多维数组:

/**

 * Title: 

 * Description: 

 * Company: Augmentum Inc<br>

 * Copyright: 2008 (c) Thinking in Java<br>

 * @author: Forest He

 * @version: 1.0

 */

package com.augmentum.foresthe;

import java.util.Random;



public class MultiDimArray {

	static Random rand = new Random();

	public static void main(String[] args) {

		/**

		 * 2-D array with fixed length, 花括号标出了数组中的每个向量

		 */

		int[][] a1 = { {1, 2, 3}, {4, 5, 6}, };

		for (int i = 0; i < a1.length; i++) 

			for (int j = 0; j < a1[i].length; j++) 

				System.out.println("a1[" + i + "][" + j + "] = " + a1[i][j]);

		/**

		 * 3-D array with fixed length, 数组分配是一次完成的

		 */

		int[][][] a2 = new int[2][2][4];

		for (int i = 0; i < a2.length; i++)

			for (int j = 0; j < a2[i].length; j++)

				for (int k = 0; k < a2[i][j].length; k++) 

					System.out.println("a2[" + i + "][" + j + "][" + k + "] = " + a2[i][j][k]);

		/**

		 * 3-D array with varied-length vectors, 数组中用以构成矩阵的向量可以有任意的长度

		 * 不规则形状的数组

		 */

		int[][][] a31 = new int[rand.nextInt(5)][][];

		for (int i = 0; i < a31.length; i++) {

			a31[i] = new int[rand.nextInt(4)][];

			for (int j = 0; j < a31[i].length; j++) a31[i][j] = new int[rand.nextInt(3)];

		}

		for (int i = 0; i < a31.length; i++) 

			for (int j = 0; j < a31[i].length; j++) 

				for (int k = 0; k < a31[i][j].length; k++) 

					System.out.println("a31[" + i + "][" + j + "][" + k + "] = " + a31[i][j][k]);

		/**

		 * 3-D array with varied-length vectors

		 * 矩形形状的数组

		 */

		int[][][] a32 = new int[rand.nextInt(5)][rand.nextInt(4)][rand.nextInt(3)];

		for (int i = 0; i < a32.length; i++) 

			for (int j = 0; j < a32[i].length; j++) 

				for (int k = 0; k < a32[i][j].length; k++) 

					System.out.println("a32[" + i + "][" + j + "][" + k + "] = " + a32[i][j][k]);

		/**

		 * Array of nonprimitive objects 1

		 */

		Integer[][] a4 = { 

						{ new Integer(1), new Integer(2), },

						{ new Integer(3), new Integer(4), },

						{ new Integer(5), new Integer(6), },

		};

		for (int i = 0; i < a4.length; i++) 

			for (int j = 0; j < a4[i].length; j++) 

				System.out.println("a4[" + i + "][" + j + "] = " + a4[i][j]);

		/**

		 * Array of nonprimitive objects 2

		 */

		Integer[][] a5;

		a5 = new Integer[3][];

		for (int i = 0; i < a5.length; i++) {

			a5[i] = new Integer[3];

			for (int j = 0; j < a5[i].length; j++) a5[i][j] = new Integer(i * j);

		}

		for (int i = 0; i < a5.length; i++) 

			for (int j = 0; j < a5[i].length; j++) 

				System.out.println("a5[" + i + "][" + j + "] = " + a5[i][j]);

	}

}
  
  
 
关于数组的新东西:所有数组(无论它们的元素是对象还是基本类型)都有一个固有成员,可以通过它获知数组内包含了多少个元素,但不能对其修改。这个成员就是length。与C和C++类似,Java数组记数也是从第0个元素开始,所以能使用的最大下标数是“length - 1”。要是超出这个边界,C和C++会“默默”地接受,并允许你访问所有内存,许多声名狼藉的程序错误由此而来。Java则能保护你免受这一问题的困扰,一旦访问下标过界,就会出现运行时错误(即异常)。当然,每次访问数组的时候都要检查边界的做法在时间和代码上都是需要开销的,但是无法禁用这个功能。这意味着如果数组访问发生在一些关键节点上,它们有可能会成为导致程序效率低下的原因之一。但是基于“因特网的安全以及提高程序员生产力”的理由,Java的设计者认为这种权衡是值得的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值