黑马程序员技术交流社区

标题: 历史上的 Collection 类 ― 数组 [打印本页]

作者: 如梦初醒    时间: 2012-4-13 23:43
标题: 历史上的 Collection 类 ― 数组
数组是在 Java 编程语言中定义的唯一的 Collection 支持。它们是按照 索引可访问的顺序或位置次序来存储一组元素的对象。它们是 Object 类的子类,实现了 Serializable 和 Cloneable 两种接口。这里没有 .java 源文件让您了解内部是如何工作的。基本上,您要创建一个有特定大小和元素类型的数组,然后填充它。

注意:因为数组是 Object 的子类,所以您可以同步数组变量并调用它的 wait() 和 notify() 方法。

让我们看一下使用数组对象能够做些什么 ― 从基本用法和声明开始,然后到复制和克隆。我们还将了解数组赋值、等同性检查以及反射。

数组基础知识

在讨论声明、创建、初始化以及复制数组的细节问题之前,让我们先复习一个简单的数组示例。当创建一个 Java 应用程序时, main() 方法有个唯一的字符串数组参数: public static void main(String args []) 。编译器并不在意您用什么参数名,只在意它是不是一个 String 对象的数组。

假设现在我们有个作为 String 对象数组的应用程序的命令行参数,我们可以观察每个元素并打印它。在 Java 中,数组知道它们的大小,而且它们总是从位置零开始建立索引。因此,我们可以通过观察数组专用的实例变量:length 来询问这个数组有多大。下面的代码展示了如何做到这一点:

public class ArrayArgs {
  public static void main (String args[]) {
    for (int i=0, n=args.length; i<n; i++) {
      System.out.println("Arg " + i +":" + args);
    }
  }
}


注意:数组索引不能是 long 类型,因为只有非负整数才可以被用作索引,因此通过从 0 到 2 31-1 的索引范围有效地将数组元素的数量限制在 2,147,483,648 或 2 31个。

因为在遍历循环时数组大小不变,这就没有必要在每次测试条件中查看 length 了,例如: for (int i=0; i<args.length; i++) 。事实上,在大多数情况下,不用递增而用递减遍历循环,并用零作测试条件通常会更快: for (int i=args.length-1; i>=0; i -) 。虽然在 JDK 1.1 和 1.2 发行版中,递减计数与递增计数相比只有相对较小的性能差异,但这个时间差异在 1.3 发行版中却更为显著。为在您的平台上演示这种速度差异,请尝试运行清单 2-1 中的程序,测试循环“max int”(int 类型的最大值,即 2 的 31 次方减 1)次所需要的时间:
对循环性能计时

public class TimeArray {
  public static void main (String args[]) {
    int something = 2;
    long startTime = System.currentTimeMillis();
    for (int i=0, n=Integer.MAX_VALUE; i<n; i++) {
      something =- something;
    }
    long midTime = System.currentTimeMillis();
    for (int i=Integer.MAX_VALUE-1; i>=0; i-) {
      something = -something;
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Increasing Delta: " + (midTime - startTime));
    System.out.println("Decreasing Delta: " + (endTime - midTime));
  }
}


这个测试程序实际上是对 for 循环进行计时而不是对数组存取进行计时,因为这里没有数组存取。

注意:在大多数情况下,在我的 400 MHz Windows NT 操作系统环境的 JDK 1.1 和 1.2 下,计数值低于 11,000 秒内。但在 JDK1.3 下,并用 -classic 选项(没有 JIT),计数值增加到 250,000 左右。甚至用 HotSpot VM with 1.3,计数值也只介于 19,000 和 30,000 之间。

如果你试图访问在数组头部前面或者尾部以后的内容,一个 ArrayIndexOutOfBoundsException 异常将被抛出。作为 IndexOutOfBoundsException 类的子类, ArrayIndexOutOfBoundsException 是一个运行时异常,如图 2-1 所示。感到高兴的是:这意味着您不必将数组存取放入 try-catch 代码块了。此外,因为查看数组上下界之外的内容是一个运行时异常,所以您的程序会编译得很好。而程序将只在我们试图存取时抛出异常。





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2