在任何集合类中,必须通过某种方法在其中置入对象,再用另一种方法从中取得对象。毕竟,容纳各种各样的对象正是集合的首要任务。在Vector中,addElement()便是我们插入对象采用的方法,而elementAt()是提取对象的唯一方法。Vector非常灵活,我们可在任何时候选择任何东西,并可使用不同的索引选择多个元素。

若从更高的角度看这个问题,就会发现它的一个缺陷:需要事先知道集合的准确类型,否则无法使用。乍看来,这一点似乎没什么关系。但假若最开始决定使用Vector,后来在程序中又决定(考虑执行效率的原因)改变成一个List(属于java1.2集合库的一部分),这时又该如何做呢?

可利用“反复器”(Iterator)的概念达到这个目的。它可以是一个对象,作用是遍历一系列对象,并选择那个序列中的每个对象,同时不让客户程序员知道或关注那个序列的基础结构。此外,我们通常认为反复器是一种“轻量级”对象;也就是说,创建它只需付出极少的代价。但也正是由于这个原因,我们常发现反复器存在一些似乎很奇怪的限制。例如,有些反复器只能朝一个方向移动。

Java的Enumeration(枚举,注释②)便是具有这些限制的一个反复器的例子。除下面这些外,不可再用它做其他任何事情:

(1) 用一个名为elements()的方法要求集合为我们提供一个Enumeration。我们首次调用它的nextElement()时,这个Enumeration会返回序列中的第一个元素。

(2) 用nextElement()获得下一个对象。

(3) 用hasMoreElements()检查序列中是否还有更多的对象。

②:“反复器”这个词在C++和OOP的其他地方是经常出现的,所以很难确定为什么Java的开发者采用了这样一个奇怪的名字。Java 1.2的集合库修正了这个问题以及其他许多问题。

只可用Enumeration做这些事情,不能再有更多。它属于反复器一种简单的实现方式,但功能依然十分强大。为体会它的运作过程,让我们复习一下本章早些时候提到的CatsAndDogs.java程序。在原始版本中,elementAt()方法用于选择每一个元素,但在下述修订版中,可看到使用了一个“枚举”:

//: CatsAndDogs2.java

// Simple collection with Enumeration

import java.util.*;

class Cat2 {

private int catNumber;

Cat2(int i) {

catNumber = i;

}

void print() {

System.out.println("Cat number " +catNumber);

}

}

class Dog2 {

private int dogNumber;

Dog2(int i) {

dogNumber = i;

}

void print() {

System.out.println("Dog number " +dogNumber);

}

}

public class CatsAndDogs2 {

public static void main(String[] args) {

Vector cats = new Vector();

for(int i = 0; i < 7; i++)

cats.addElement(new Cat2(i));

// Not a problem to add a dog to cats:

cats.addElement(new Dog2(7));

Enumeration e = cats.elements();

while(e.hasMoreElements())

((Cat2)e.nextElement()).print();

// Dog is detected only at run-time

}

} ///:~

我们看到唯一的改变就是最后几行。不再是:

for(int i = 0; i < cats.size(); i++)

((Cat)cats.elementAt(i)).print();

而是用一个Enumeration遍历整个序列:

while(e.hasMoreElements())

((Cat2)e.nextElement()).print();

使用Enumeration,我们不必关心集合中的元素数量。所有工作均由hasMoreElements()和nextElement()自动照管了。

下面再看看另一个例子,让我们创建一个常规用途的打印方法:

//: HamsterMaze.java

// Using an Enumeration

import java.util.*;

class Hamster {

private int hamsterNumber;

Hamster(int i) {

hamsterNumber = i;

}

public String toString() {

return "This is Hamster #" + hamsterNumber;

}

}

class Printer {

static void printAll(Enumeration e) {

while(e.hasMoreElements())

System.out.println(

e.nextElement().toString());

}

}

public class HamsterMaze {

public static void main(String[] args) {

Vector v = new Vector();

for(int i = 0; i < 3; i++)

v.addElement(new Hamster(i));

Printer.printAll(v.elements());

}

} ///:~

仔细研究一下打印方法:

static void printAll(Enumeration e) {

while(e.hasMoreElements())

System.out.println(

e.nextElement().toString());

}

注意其中没有与序列类型有关的信息。我们拥有的全部东西便是Enumeration。为了解有关序列的情况,一个Enumeration便足够了:可取得下一个对象,亦可知道是否已抵达了末尾。取得一系列对象,然后在其中遍历,从而执行一个特定的操作——这是一个颇有价值的编程概念,本书许多地方都会沿用这一思路。

这个看似特殊的例子甚至可以更为通用,因为它使用了常规的toString()方法(之所以称为常规,是由于它属于Object类的一部分)。下面是调用打印的另一个方法(尽管在效率上可能会差一些):

System.out.println("" + e.nextElement());

它采用了封装到Java内部的“自动转换成字串”技术。一旦编译器碰到一个字串,后面跟随一个“+”,就会希望后面又跟随一个字串,并自动调用toString()。在Java 1.1中,第一个字串是不必要的;所有对象都会转换成字串。亦可对此执行一次造型,获得与调用toString()同样的效果:

System.out.println((String)e.nextElement())

但我们想做的事情通常并不仅仅是调用Object方法,所以会再度面临类型造型的问题。对于自己感兴趣的类型,必须假定自己已获得了一个Enumeration,然后将结果对象造型成为那种类型(若操作错误,会得到运行期违例)。

java 反复器_java集合类中的枚举器(反复器)相关推荐

  1. java8默认垃圾收集器_Java 8中最快的垃圾收集器是什么?

    java8默认垃圾收集器 OpenJDK 8具有几种垃圾收集器算法,例如Parallel GC , CMS和G1 . 哪一个最快? 如果默认GC从Java 8中的并行GC更改为Java 9中的G1(当 ...

  2. java9 g1垃圾收集器_Java 9中默认为G1垃圾收集器的情况

    java9 g1垃圾收集器 在前面的几篇文章中,我已经在InfoQ上介绍并讨论了"垃圾第一垃圾收集器" -G1:一个由所有垃圾收集器来统治它们以及调整垃圾第一垃圾收集器的技巧 . ...

  3. android xml java混合编程_Java学习中注解与多线程,网络编程与XML技术

    本部分内容主要有集合框架及泛型,实用类,输入和输出处理,注解与多线程,网络编程与XML技术.初次学习这部分会感觉很难,主要是概念难于理解,最好是多看看例子,多练习.下面是个人的总结 拉勾IT课小编为大 ...

  4. java类加载器_java底层内功 第一章,类加载器的任性

    java类是怎么加载的? 类加载机制 JVM主要包含三大核心部分:类加载器,运行时数据区和执行引擎. 虚拟机将描述类的数据从class文件加载到内存,并对数据进行校验,准备,解析和初始化,最终就会形成 ...

  5. java swing背景_java Swing中添加背景图片(总结)

    在java GUI图形化设计中,Swing组件添加背景图片主要有两中情况:1,在Jpanl面板中添加背景图片,2,在jLable中添加背景图片 首先介绍一种最巧妙的背景图片添加方法, 1.利用JLab ...

  6. java的成员方法_java编程中的成员方法是什么?

    DIEA 成员方法描述对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块.它与过去所说的子程序.函数等概念相当.一个类或对象可以有多个成员方法,对象通过执行它的成员方法对传来的消 ...

  7. java注解和python装饰器_Java 的注解 和 Python 的装饰器 是一回事吗?

    长得像,但却是两个物种,不过可以让他们表现得近似. Python 的装饰器正如他的名称,很直白,就是实现了装饰器模式(的一个语法糖).@部分对应一个返回为函数的函数,可以对目标函数进行输入.输出过滤, ...

  8. java runnable 异常_JAVA 线程中的异常捕获

    在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked e ...

  9. java垃圾收集方法_java几种垃圾收集方法和垃圾收集器

    标记清除法: 分为两个阶段,标记----清除 标记阶段将所有需要回收的对象做标记,然后在清除阶段将所有的标记对象回收 但是这种回收方法有很大的缺点,那就是这两个过程的的效率并不高,两个过程都是效率很低 ...

最新文章

  1. EST | 系统评价污水样品中选定药物、非法药物及其代谢物的稳定性
  2. Nginx配置文件详细说明
  3. Java线程池--ThreadPoolExecutor
  4. 湖南大学计算机系统原理实验,湖南大学-计算机组成原理实验-实验3-bomblab_图文.pdf...
  5. Struts2中访问HttpServletRequest和HttpSession
  6. nginx 二进制包安装mysql_二进制安装mysql5.7
  7. iBatis的基本配置+CRUD操作
  8. 随想录(c语言的优缺点)
  9. oracle语法_PG数据库sql语法总结,与Oracle有什么不同?
  10. 程序老鸟:软件测试的工资高还是开发者工资高?
  11. 芯片国产化进程提速 赶超洋品牌核心技术尚欠火候
  12. 轻松学网络设备之思科交换机搭建虚拟局域网
  13. 15串行加法器和并行加法器原理
  14. vue echarts饼状图内部显示百分比
  15. xp计算机用户账户密码删除,xp强行删除管理员开机密码
  16. 简单的图形识别python
  17. Android 做一个简单记事本app
  18. 软著申请全流程图文解析与注意事项
  19. 使用Scylla获取免费代理IP
  20. avr模拟串口通讯c语言,AVR的模拟串口的问题

热门文章

  1. 编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n。如果输入的是奇数调用1/1+1/3+...+1/n;...
  2. 开发更安全的asp.net应用程序一
  3. linux 病毒 sfewfesfs
  4. 5 个用于在 Linux 终端中查找域名 IP 地址的命令
  5. Linux中echo 返回值的意思
  6. 【Oracle】ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
  7. 设置hash后导致的返回问题的解决方案
  8. PLSQL无法连接64位Oracle数据库/Database下拉框为空的解决方法
  9. 解决maven打包打不进lib下的第三方jar包问题
  10. TypeError: ‘builtin_function_or_method‘ object is not subscriptable 报错解决方法