⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter08.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    GopherVector gophers = <font color=#0000ff>new</font> GopherVector();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 3; i++)
      gophers.addElement(<font color=#0000ff>new</font> Gopher(i));
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; gophers.size(); i++)
      GopherTrap.caughtYa(gophers.elementAt(i));
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This is similar to the previous
example, except that the new <B>GopherVector</B> class has a <B>private
</B>member of type <B>Vector</B> (inheriting from <B>Vector</B> tends to be
frustrating, for reasons you&#8217;ll see later), and methods just like
<B>Vector</B>. However, it doesn&#8217;t accept and produce generic
<B>Object</B>s, only <B>Gopher</B> objects.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Because a <B>GopherVector</B> will
accept only a <B>Gopher</B>, if you were to say:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>gophers.addElement(<font color=#0000ff>new</font> Pigeon());</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">you would get an error message
<I>at compile time</I>. This approach, while more tedious from a coding
standpoint, will tell you immediately if you&#8217;re using a type
improperly.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that no cast is necessary when
using <B>elementAt(&#160;)</B> &#8211; it&#8217;s always a
<B>Gopher</B>.</FONT><BR></P></DIV>
<A NAME="Heading248"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Parameterized types</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This kind of problem isn&#8217;t
isolated &#8211; there are numerous cases in which you need to create new types
based on other types, and in which it is useful to have specific type
information at compile-time. This is the concept of a
<A NAME="Index757"></A><A NAME="Index758"></A><I>parameterized type</I>. In C++,
this is directly supported by the language in
<A NAME="Index759"></A><A NAME="Index760"></A><I>templates</I>. At one point,
Java had reserved the keyword <A NAME="Index761"></A><B>generic</B> to someday
support parameterized types, but it&#8217;s uncertain if this will ever
occur.</FONT><A NAME="_Toc375545352"></A><A NAME="_Toc408018568"></A><BR></P></DIV>
<A NAME="Heading249"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Enumerators (iterators)</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In any collection class, you must
have a way to put things in and a way to get things out. After all, that&#8217;s
the primary job of a collection &#8211; to hold things. In the
<A NAME="Index762"></A><B>Vector</B>, <B>addElement(&#160;)</B> is the way that
you insert objects, and <B>elementAt(&#160;)</B> is <I>one</I> way to get things
out. <B>Vector</B> is quite flexible &#8211; you can select anything at any
time, and select multiple elements at once using different
indexes.<A NAME="Index763"></A><A NAME="Index764"></A></FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you want to start thinking at a
higher level, there&#8217;s a drawback: you need to know the exact type of the
collection in order to use it. This might not seem bad at first, but what if you
start out using a <B>Vector</B>, and later on in your program you decide, for
efficiency, that you want to change to a <B>List</B> (which is part of the Java
1.2<A NAME="Index765"></A> collections library)? Or you&#8217;d like to write a
piece of code that doesn&#8217;t know or care what type of collection it&#8217;s
working with.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The concept of an
<A NAME="Index766"></A><I>iterator </I>can be used to achieve this next level of
abstraction. This is an object whose job is to move through a sequence of
objects and select each object in that sequence without the client programmer
knowing or caring about the underlying structure of that sequence. In addition,
an iterator is usually what&#8217;s called a &#8220;light-weight&#8221; object;
that is, one that&#8217;s cheap to create. For that reason, you&#8217;ll often
find seemingly strange constraints for iterators; for example, some iterators
can move in only one direction.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java
<B>Enumeration</B></FONT><A NAME="fnB33" HREF="#fn33">[33]</A><FONT FACE="Georgia">
is an example of an iterator with these kinds of constraints. There&#8217;s not
much you can do with one except: <A NAME="Index767"></A></FONT><BR></P></DIV>
<OL>
<LI><FONT FACE="Georgia">	Ask a collection to hand you an <B>Enumeration
</B>using a method called <B>elements(&#160;)</B>.<B> </B>This <B>Enumeration
</B>will be ready to return the first element in the sequence on your first call
to its <B>nextElement(&#160;)</B>
method.</FONT><LI><FONT FACE="Georgia">	Get the next object in the
sequence with
<B>nextElement(&#160;).</B></FONT><LI><FONT FACE="Georgia">	See if there
<I>are</I> any more objects in the sequence with
<B>hasMoreElements(&#160;).</B></FONT></OL><DIV ALIGN="LEFT"><P><FONT FACE="Georgia">That&#8217;s
all. It&#8217;s a simple implementation of an iterator, but still powerful. To
see how it works, let&#8217;s revisit the <B>CatsAndDogs.java</B> program from
earlier in the chapter. In the original version, the method
<B>elementAt(&#160;)</B> was used to select each element, but in the following
modified version an enumeration is used:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: CatsAndDogs2.java</font>
<font color=#009900>// Simple collection with Enumeration</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>class</font> Cat2 {
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> catNumber;
  Cat2(<font color=#0000ff>int</font> i) {
    catNumber = i;
  }
  <font color=#0000ff>void</font> print() {
    System.out.println(<font color=#004488>"Cat number "</font> +catNumber);
  }
}

<font color=#0000ff>class</font> Dog2 {
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> dogNumber;
  Dog2(<font color=#0000ff>int</font> i) {
    dogNumber = i;
  }
  <font color=#0000ff>void</font> print() {
    System.out.println(<font color=#004488>"Dog number "</font> +dogNumber);
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> CatsAndDogs2 {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Vector cats = <font color=#0000ff>new</font> Vector();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 7; i++)
      cats.addElement(<font color=#0000ff>new</font> Cat2(i));
    <font color=#009900>// Not a problem to add a dog to cats:</font>
    cats.addElement(<font color=#0000ff>new</font> Dog2(7));
    Enumeration e = cats.elements();
    <font color=#0000ff>while</font>(e.hasMoreElements())
      ((Cat2)e.nextElement()).print();
    <font color=#009900>// Dog is detected only at run-time</font>
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can see that the only change is
in the last few lines. Instead of:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; cats.size(); i++)
      ((Cat)cats.elementAt(i)).print();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">an <B>Enumeration</B> is used to
step through the sequence:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>while</font>(e.hasMoreElements())
      ((Cat2)e.nextElement()).print();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">With the <B>Enumeration</B>, you
don&#8217;t need to worry about the number of elements in the collection.
That&#8217;s taken care of for you by
<A NAME="Index768"></A><A NAME="Index769"></A><B>hasMoreElements(&#160;)</B> and
<A NAME="Index770"></A><A NAME="Index771"></A><B>nextElement(&#160;)</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As another example, consider the
creation of a general-purpose printing method:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: HamsterMaze.java</font>
<font color=#009900>// Using an Enumeration</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>class</font> Hamster {
  <font color=#0000ff>private</font> <font color=#0000ff>int</font> hamsterNumber;
  Hamster(<font color=#0000ff>int</font> i) {
    hamsterNumber = i;
  }
  <font color=#0000ff>public</font> String toString() {
    <font color=#0000ff>return</font> <font color=#004488>"This is Hamster #"</font> + hamsterNumber;
  }
}

<font color=#0000ff>class</font> Printer {
  <font color=#0000ff>static</font> <font color=#0000ff>void</font> printAll(Enumeration e) {
    <font color=#0000ff>while</font>(e.hasMoreElements())
      System.out.println(
        e.nextElement().toString());
  }
}

<font color=#0000ff>public</font> <font color=#0000ff>class</font> HamsterMaze {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Vector v = <font color=#0000ff>new</font> Vector();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 3; i++)
      v.addElement(<font color=#0000ff>new</font> Hamster(i));
    Printer.printAll(v.elements());
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Look closely at the printing
method:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>static</font> <font color=#0000ff>void</font> printAll(Enumeration e) {
  <font color=#0000ff>while</font>(e.hasMoreElements())
    System.out.println(
      e.nextElement().toString());
}</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Note that there&#8217;s no
information about the type of sequence. All you have is an <B>Enumeration</B>,
and that&#8217;s all you need to know about the sequence: that you can get the
next object, and that you can know when you&#8217;re at the end. This idea of
taking a collection of objects and passing through it to perform an operation on
each one is powerful and will be seen throughout this book.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This particular example is even
more generic, since it uses the ubiquitous
<A NAME="Index772"></A><B>toString(&#160;)</B> method (ubiquitous only because
it&#8217;s part of the <B>Object</B> class). An alternative way to call print
(although probably slightly less efficient, if you could even notice the
difference) is: </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>System.out.println(<font color=#004488>""</font> + e.nextElement());</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><A NAME="Index773"></A><A NAME="Index774"></A><FONT FACE="Georgia">which
uses the &#8220;automatic conversion to <B>String</B>&#8221; that&#8217;s wired
into Java. When the compiler sees a <B>String</B>, followed by a
&#8216;<B>+</B>&#8217;, it expects another <B>String</B> to follow and calls
<B>toString(&#160;)</B> automatically. (In <A NAME="Index775"></A>Java 1.1, the
first <B>String</B> is unnecessary; any object will be converted to a
<B>String.</B>) You can also perform a cast, which has the effect of calling
<B>toString(&#160;)</B>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>System.out.println((String)e.nextElement());</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In general, however, you&#8217;ll
want to do something more than call <B>Object</B> methods, so you&#8217;ll run
up against the type-casting issue again. You must assume you&#8217;ve gotten an
<B>Enumeration</B> to a sequence of the particular type you&#8217;re interested
in, and cast the resulting objects to that type (getting a run-time exception if
you&#8217;re
wrong).</FONT><A NAME="_Toc375545353"></A><A NAME="_Toc408018569"></A><BR></P></DIV>
<A NAME="Heading250"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Types of collections</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The standard Java
1.0<A NAME="Index776"></A> and 1.1 library comes with a bare minimum set of
collection classes, but they&#8217;re probably enough to get by with for many of
your programming projects. (As you&#8217;ll see at the end of this chapter, Java

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -