java的列举器(重复器)
当前位置:以往代写 > JAVA 教程 >java的列举器(重复器)
2019-06-14

java的列举器(重复器)

java的列举器(重复器)

在任何荟萃类中,必需通过某种要领在个中置入工具,再用另一种要领从中取得工具。究竟,容纳各类百般的工具正是荟萃的首要任务。在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,然后将功效工具造型成为那种范例(若操纵错误,会获得运行期违例)。

    关键字:

在线提交作业