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

📄 chapter08.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
1.2<A NAME="Index777"></A> provides a radically redesigned and filled-out
library of collections.)
</FONT><A NAME="_Ref348399519"></A><A NAME="_Toc375545354"></A><A NAME="_Toc408018570"></A><BR></P></DIV>
<A NAME="Heading251"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Vector<BR><A NAME="Index778"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>Vector</B> is quite simple
to use, as you&#8217;ve seen so far. Although most of the time you&#8217;ll just
use <B>addElement(&#160;)</B> to insert objects, <B>elementAt(&#160;)</B> to get
them out one at a time, and <B>elements(&#160;)</B> to get an <B>Enumeration</B>
to the sequence, there&#8217;s also a set of other methods that can be useful.
As usual with the Java libraries, we won&#8217;t use or talk about them all
here, but be sure to look them up in the electronic documentation to get a feel
for what they can do.</FONT><BR></P></DIV>
<A NAME="Heading252"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Crashing Java<BR><A NAME="Index779"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java standard collections
contain a <B>toString(&#160;)</B> method so they can produce a <B>String</B>
representation of themselves, including the objects they hold. Inside of
<B>Vector</B>, for example, the <B>toString(&#160;)</B> steps through the
elements of the <B>Vector</B> and calls <B>toString(&#160;)</B> for each one.
Suppose you&#8217;d like to print out the address of your class. It seems to
make sense to simply refer to <B>this </B>(in particular, C++ programmers are
prone to this approach):</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: CrashJava.java</font>
<font color=#009900>// One way to crash Java</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> CrashJava {
  <font color=#0000ff>public</font> String toString() {
    <font color=#0000ff>return</font> <font color=#004488>"CrashJava address: "</font> + <font color=#0000ff>this</font> + <font color=#004488>"\n"</font>;
  }
  <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; 10; i++)
      v.addElement(<font color=#0000ff>new</font> CrashJava());
    System.out.println(v);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It turns out that if you simply
create a <B>CrashJava</B> object and print it out, you&#8217;ll get an endless
sequence of exceptions. However, if you place the <B>CrashJava</B> objects in a
<B>Vector</B> and print out that <B>Vector</B> as shown here, it can&#8217;t
handle it and you don&#8217;t even get an exception; Java just crashes. (But at
least it didn&#8217;t bring down my operating system.) This was tested with Java
1.1<A NAME="Index780"></A>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What&#8217;s happening is automatic
type conversion for <B>String</B>s. When you say: </FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#004488>"CrashJava address: "</font> + <font color=#0000ff>this</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The compiler sees a <B>String</B>
followed by a &#8216;<B>+</B>&#8217; and<B> </B>something that&#8217;s not a
<B>String</B>, so it tries to convert <B>this</B> to a <B>String</B>. It does
this conversion by calling <B>toString(&#160;)</B>, which produces a
<A NAME="Index781"></A><A NAME="Index782"></A>recursive call. When this occurs
inside a <B>Vector,</B> it appears that the
<A NAME="Index783"></A><A NAME="Index784"></A>stack overflows without the
exception-handling mechanism getting a chance to respond.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you really do want to print the
address of the object in this case, the solution is to call the <B>Object</B>
<B>toString(&#160;)</B> method, which does just that. So instead of saying
<B>this</B>, you&#8217;d say <B>super.toString(&#160;)</B>. (This only works if
you're directly inheriting from <B>Object</B> or if none of your parent classes
have overridden the <B>toString(&#160;)</B>
method).</FONT><A NAME="_Toc375545355"></A><A NAME="_Toc408018571"></A><BR></P></DIV>
<A NAME="Heading253"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
BitSet</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A
<A NAME="Index785"></A><B>BitSet</B> is really a <B>Vector</B> of bits, and it
is used if you want to efficiently store a lot of on-off information. It&#8217;s
efficient only from the standpoint of size; if you&#8217;re looking for
efficient access, it is slightly slower than using an array of some native
type.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In addition, the minimum size of
the <B>BitSet</B> is that of a long: 64 bits. This implies that if you&#8217;re
storing anything smaller, like 8 bits, a <B>BitSet</B> will be wasteful, so
you&#8217;re better off creating your own class to hold your
flags.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In a normal <B>Vector</B>, the
collection will expand as you add more elements. The <B>BitSet</B> does this as
well &#8211; sort of. That is, sometimes it works and sometimes it
doesn&#8217;t, which makes it appear that the Java version 1.0 implementation of
<B>BitSet</B> is just badly done. (It is fixed in Java
1.1.<A NAME="Index786"></A>) The following example shows how the <B>BitSet
</B>works and demonstrates the version 1.0 bug:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Bits.java</font>
<font color=#009900>// Demonstration of BitSet</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Bits {
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Random rand = <font color=#0000ff>new</font> Random();
    <font color=#009900>// Take the LSB of nextInt():</font>
    <font color=#0000ff>byte</font> bt = (<font color=#0000ff>byte</font>)rand.nextInt();
    BitSet bb = <font color=#0000ff>new</font> BitSet();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 7; i &gt;=0; i--)
      <font color=#0000ff>if</font>(((1 &lt;&lt; i) &amp;  bt) != 0)
        bb.set(i);
      <font color=#0000ff>else</font>
        bb.clear(i);
    System.out.println(<font color=#004488>"byte value: "</font> + bt);
    printBitSet(bb);

    <font color=#0000ff>short</font> st = (<font color=#0000ff>short</font>)rand.nextInt();
    BitSet bs = <font color=#0000ff>new</font> BitSet();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 15; i &gt;=0; i--)
      <font color=#0000ff>if</font>(((1 &lt;&lt; i) &amp;  st) != 0)
        bs.set(i);
      <font color=#0000ff>else</font>
        bs.clear(i);
    System.out.println(<font color=#004488>"short value: "</font> + st);
    printBitSet(bs);

    <font color=#0000ff>int</font> it = rand.nextInt();
    BitSet bi = <font color=#0000ff>new</font> BitSet();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 31; i &gt;=0; i--)
      <font color=#0000ff>if</font>(((1 &lt;&lt; i) &amp;  it) != 0)
        bi.set(i);
      <font color=#0000ff>else</font>
        bi.clear(i);
    System.out.println(<font color=#004488>"int value: "</font> + it);
    printBitSet(bi);

    <font color=#009900>// Test bitsets &gt;= 64 bits:</font>
    BitSet b127 = <font color=#0000ff>new</font> BitSet();
    b127.set(127);
    System.out.println(<font color=#004488>"set bit 127: "</font> + b127);
    BitSet b255 = <font color=#0000ff>new</font> BitSet(65);
    b255.set(255);
    System.out.println(<font color=#004488>"set bit 255: "</font> + b255);
    BitSet b1023 = <font color=#0000ff>new</font> BitSet(512);
<font color=#009900>// Without the following, an exception is thrown</font>
<font color=#009900>// in the Java 1.0 implementation of BitSet:</font>
<font color=#009900>//    b1023.set(1023);</font>
    b1023.set(1024);
    System.out.println(<font color=#004488>"set bit 1023: "</font> + b1023);
  }
  <font color=#0000ff>static</font> <font color=#0000ff>void</font> printBitSet(BitSet b) {
    System.out.println(<font color=#004488>"bits: "</font> + b);
    String bbits = <font color=#0000ff>new</font> String();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; b.size() ; j++)
      bbits += (b.get(j) ? <font color=#004488>"1"</font> : <font color=#004488>"0"</font>);
    System.out.println(<font color=#004488>"bit pattern: "</font> + bbits);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The random number generator is used
to create a random <B>byte</B>, <B>short</B>, and <B>int</B>, and each one is
transformed into a corresponding bit pattern in a <B>BitSet</B>. This works fine
because a <B>BitSet</B> is 64 bits, so none of these cause it to increase in
size. But in Java 1.0<A NAME="Index787"></A>, when the <B>BitSet</B> is greater
than 64 bits, some strange behavior occurs. If you set a bit that&#8217;s just
one greater than the <B>BitSet</B>&#8217;s currently-allocated storage, it will
expand nicely. But if you try to set bits at higher locations than that without
first just touching the boundary, you&#8217;ll get an exception, since the
<B>BitSet</B> won&#8217;t expand properly in Java 1.0. The example shows a
<B>BitSet</B> of 512 bits being created. The constructor allocates storage for
twice that number of bits. Then if you try to set bit 1024 or greater without
first setting bit 1023, you&#8217;ll throw an exception in
<A NAME="Index788"></A>Java 1.0. Fortunately, this is fixed in Java
1.1,<A NAME="Index789"></A> but avoid using the <B>BitSet</B> if you write code
for Java
1.0.</FONT><A NAME="_Toc375545356"></A><A NAME="_Toc408018572"></A><BR></P></DIV>
<A NAME="Heading254"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Stack</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A
<A NAME="Index790"></A><B>Stack</B> is sometimes referred to as a
&#8220;last-in, first-out&#8221; (LIFO) collection. That is, whatever you
&#8220;push&#8221; on the <B>Stack</B> last is the first item you can
&#8220;pop&#8221; out. Like all of the other collections in Java, what you push
and pop are <B>Object</B>s, so you must cast what you pop.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What&#8217;s rather odd is that
instead of using a <A NAME="Index791"></A><B>Vector</B> as a building block to
create a <B>Stack</B>, <B>Stack </B>is inherited from <B>Vector</B>. So it has
all of the characteristics and behaviors of a <B>Vector</B> <I>plus</I> some
extra <B>Stack</B> behaviors. It&#8217;s difficult to know whether the designers
explicitly decided that this was an especially useful way to do things, or
whether it was just a na&iuml;ve design.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s a simple demonstration
of <B>Stack</B> that reads each line from an array and pushes it as a
<B>String</B>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Stacks.java</font>
<font color=#009900>// Demonstration of Stack Class</font>
<font color=#0000ff>import</font> java.util.*;

<font color=#0000ff>public</font> <font color=#0000ff>class</font> Stacks {
  <font color=#0000ff>static</font> String[] months = { 
    <font color=#004488>"January"</font>, <font color=#004488>"February"</font>, <font color=#004488>"March"</font>, <font color=#004488>"April"</font>,
    <font color=#004488>"May"</font>, <font color=#004488>"June"</font>, <font color=#004488>"July"</font>, <font color=#004488>"August"</font>, <font color=#004488>"September"</font>,
    <font color=#004488>"October"</font>, <font color=#004488>"November"</font>, <font color=#004488>"December"</font> };
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    Stack stk = <font color=#0000ff>new</font> Stack();
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; months.length; i++)
      stk.push(months[i] + <font color=#004488>" "</font>);
    System.out.println(<font color=#004488>"stk = "</font> + stk);
    <font color=#009900>// Treating a stack as a Vector:</font>
    stk.addElement(<font color=#004488>"The last line"</font>);
    System.out.println(
      <font color=#004488>"element 5 = "</font> + stk.elementAt(5));
    System.out.println(<font color=#004488>"popping elements:"</font>);
    <font color=#0000ff>while</font>(!stk.empty())
      System.out.println(stk.pop());
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Each line in the <B>months
</B>array is inserted into the <B>Stack</B> with <B>push(&#160;)</B>, and later
fetched from the top of the stack with a <B>pop(&#160;)</B>. To make a point,
<B>Vector </B>operations are also performed on the <B>Stack</B> object. This is
possible because, by virtue of inheritance, a <B>Stack</B> <I>is</I> a
<B>Vector</B>. Thus, all operations that can be performed on a <B>Vector</B> can
also be performed on a <B>Stack</B>, such as
<B>elementAt(&#160;)</B>.</FONT><A NAME="_Toc375545357"></A><A NAME="_Toc408018573"></A><BR></P></DIV>
<A NAME="Hea

⌨️ 快捷键说明

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