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

📄 chapter08.html

📁 java 是一个很好的网络开发环境。由于它是通过解释的方法
💻 HTML
📖 第 1 页 / 共 5 页
字号:
    System.out.println(<font color=#004488>"e.length = "</font> + e.length);
    <font color=#009900>// Java 1.1 initialization syntax:</font>
    e = <font color=#0000ff>new</font> <font color=#0000ff>int</font>[] { 1, 2 };
    System.out.println(<font color=#004488>"e.length = "</font> + e.length);
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here&#8217;s the output from the
program:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>b.length = 5
b[0]=<font color=#0000ff>null</font>
b[1]=<font color=#0000ff>null</font>
b[2]=<font color=#0000ff>null</font>
b[3]=<font color=#0000ff>null</font>
b[4]=<font color=#0000ff>null</font>
c.length = 4
d.length = 3
a.length = 3
a.length = 2
f.length = 5
f[0]=0
f[1]=0
f[2]=0
f[3]=0
f[4]=0
g.length = 4
h.length = 3
e.length = 3
e.length = 2</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The array <B>a</B> is initially
just a <A NAME="Index733"></A><B>null</B> handle, and the compiler prevents you
from doing anything with this handle until you&#8217;ve properly initialized it.
The array <B>b</B> is initialized to point to an array of <B>Weeble</B> handles,
but no actual <B>Weeble</B> objects are ever placed in that array. However, you
can still ask what the size of the array is, since <B>b</B> is pointing to a
legitimate object. This brings up a slight drawback: you can&#8217;t find out
how many elements are actually <I>in</I> the array, since <B>length</B> tells
you only how many elements <I>can</I> be placed in the array; that is, the size
of the array object, not the number of elements it actually holds. However, when
an array object is created its handles are automatically initialized to
<B>null</B> so you can see whether a particular array slot has an object in it
by checking to see whether it&#8217;s <B>null</B>. Similarly, an array of
primitives is automatically initialized to zero for numeric types, <B>null
</B>for <B>char</B>, and<B> false</B> for <B>boolean</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Array <B>c</B> shows the creation
of the array object followed by the assignment of <B>Weeble</B> objects to all
the slots in the array. Array <B>d</B> shows the &#8220;aggregate
initialization&#8221; syntax that causes the array object to be created
(implicitly with <B>new</B> on the heap, just like for array <B>c</B>)
<I>and</I> initialized with <B>Weeble</B> objects, all in one
statement.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The expression</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>a = d;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">shows how you can take a handle
that&#8217;s attached to one array object and assign it to another array object,
just as you can do with any other type of object handle. Now both <B>a</B> and
<B>d</B> are pointing to the same array object on the heap.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><A NAME="Index734"></A><FONT FACE="Georgia">Java 1.1
adds a new array initialization syntax, which could be thought of as a
&#8220;dynamic aggregate initialization.&#8221; The Java
1.0<A NAME="Index735"></A> aggregate initialization used by <B>d</B> must be
used at the point of <B>d</B>&#8217;s definition, but with the Java 1.1 syntax
you can create and initialize an array object anywhere. For example, suppose
<B>hide(&#160;)</B> is a method that takes an array of <B>Weeble</B> objects.
You could call it by saying:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>hide(d);</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">but in Java 1.1 you can also
dynamically create the array you want to pass as the argument:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE>hide(<font color=#0000ff>new</font> Weeble[] { <font color=#0000ff>new</font> Weeble(), <font color=#0000ff>new</font> Weeble() });</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This new syntax provides a more
convenient way to write code in some situations.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second part of the above
example shows that primitive arrays work just like object arrays <I>except</I>
that primitive arrays hold the primitive values
directly.</FONT><A NAME="_Toc375545349"></A><BR></P></DIV>
<A NAME="Heading242"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Collections of primitives<BR><A NAME="Index736"></A><A NAME="Index737"></A></H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Collection classes can hold only
handles to objects. An array, however, can be created to hold primitives
directly, as well as handles to objects. It <I>is</I> possible to use the
&#8220;wrapper&#8221; classes such as <B>Integer</B>, <B>Double,</B> etc. to
place primitive values inside a collection, but as you&#8217;ll see later in
this chapter in the <B>WordCount.java</B> example, the wrapper classes for
primitives are only somewhat useful anyway. Whether you put primitives in arrays
or wrap them in a class that&#8217;s placed in a collection is a question of
efficiency. It&#8217;s much more efficient to create and access an array of
primitives than a collection of wrapped primitives.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Of course, if you&#8217;re using a
primitive type and you need the flexibility of a collection that automatically
expands when more space is needed, the array won&#8217;t work and you&#8217;re
forced to use a collection of wrapped primitives. You might think that there
should be a specialized type of <B>Vector</B> for each of the primitive data
types, but Java doesn&#8217;t provide this for you. Some sort of templatizing
mechanism might someday provide a better way for Java to handle this
problem.</FONT><A NAME="fnB32" HREF="#fn32">[32]</A><A NAME="_Toc408018565"></A><BR></P></DIV>
<A NAME="Heading243"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Returning an array</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Suppose you&#8217;re writing a
method and you don&#8217;t just want to return one thing, but a whole bunch of
things. Languages like C and C++ make this difficult because you can&#8217;t
just return an array, only a pointer to an array. This introduces problems
because it becomes messy to control the lifetime of the array, which easily
leads to memory leaks.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Java takes a similar approach, but
you just &#8220;return an array.&#8221; Actually, of course, you&#8217;re
returning a handle to an array, but with Java you never worry about
responsibility for that array &#8211; it will be around as long as you need it,
and the garbage collector will clean it up when you&#8217;re
done.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As an example, consider returning
an array of <B>String</B>:</FONT><BR></P></DIV>

<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: IceCream.java</font>
<font color=#009900>// Returning arrays from methods</font>

<font color=#0000ff>public</font> <font color=#0000ff>class</font> IceCream {
  <font color=#0000ff>static</font> String[] flav = {
    <font color=#004488>"Chocolate"</font>, <font color=#004488>"Strawberry"</font>,
    <font color=#004488>"Vanilla Fudge Swirl"</font>, <font color=#004488>"Mint Chip"</font>,
    <font color=#004488>"Mocha Almond Fudge"</font>, <font color=#004488>"Rum Raisin"</font>,
    <font color=#004488>"Praline Cream"</font>, <font color=#004488>"Mud Pie"</font> 
  };
  <font color=#0000ff>static</font> String[] flavorSet(<font color=#0000ff>int</font> n) {
    <font color=#009900>// Force it to be positive &amp; within bounds:</font>
    n = Math.abs(n) % (flav.length + 1);
    String[] results = <font color=#0000ff>new</font> String[n];
    <font color=#0000ff>int</font>[] picks = <font color=#0000ff>new</font> <font color=#0000ff>int</font>[n];
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; picks.length; i++)
      picks[i] = -1;
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; picks.length; i++) {
      retry:
      <font color=#0000ff>while</font>(<font color=#0000ff>true</font>) {
        <font color=#0000ff>int</font> t =
          (<font color=#0000ff>int</font>)(Math.random() * flav.length);
        <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; i; j++)
          <font color=#0000ff>if</font>(picks[j] == t) <font color=#0000ff>continue</font> retry;
        picks[i] = t;
        results[i] = flav[t];
        <font color=#0000ff>break</font>;
      }
    }
    <font color=#0000ff>return</font> results;
  }
  <font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
    <font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i &lt; 20; i++) {
      System.out.println(
        <font color=#004488>"flavorSet("</font> + i + <font color=#004488>") = "</font>);
      String[] fl = flavorSet(flav.length);
      <font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j &lt; fl.length; j++)
        System.out.println(<font color=#004488>"\t"</font> + fl[j]);
    }
  }
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The method <B>flavorSet(&#160;)</B>
creates an array of <B>String</B> called <B>results</B>. The size of this array
is <B>n</B>, determined by the argument you pass into the method. Then it
proceeds to choose flavors randomly from the array <B>flav</B> and place them
into <B>results</B>, which it finally returns. Returning an array is just like
returning any other object &#8211; it&#8217;s a handle. It&#8217;s not important
that the array was created within <B>flavorSet(&#160;)</B>, or that the array
was created anyplace else, for that matter. The garbage collector takes care of
cleaning up the array when you&#8217;re done with it, and the array will persist
for as long as you need it.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">As an aside, notice that when
<B>flavorSet(&#160;)</B> chooses flavors randomly, it ensures that a random
choice hasn&#8217;t been picked before. This is performed in a seemingly
infinite <B>while</B> loop that keeps making random choices until it finds one
that&#8217;s not already in the <B>picks</B> array. (Of course, a <B>String</B>
comparison could also have been performed to see if the random choice was
already in the <B>results</B> array, but <B>String</B> comparisons are
inefficient.) If it&#8217;s successful it adds the entry and <B>break</B>s out
to go find the next one (<B>i </B>gets incremented). But if <B>t</B> is a number
that&#8217;s already in <B>picks</B>, then a labeled <B>continue</B> is used to
jump back two levels, which forces a new <B>t</B> to be selected. It&#8217;s
particularly convincing to watch this happen with a debugger.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia"><B>main(&#160;)</B> prints out 20
full sets of flavors, so you can see that <B>flavorSet(&#160;)</B> chooses the
flavors in a random order each time. It&#8217;s easiest to see this if you
redirect the output into a file. And while you&#8217;re looking at the file,
remember, you&#8217;re not really hungry. (You just <I>want</I> the ice cream,
you don&#8217;t <I>need</I>
it.)</FONT><A NAME="_Toc375545350"></A><A NAME="_Toc408018566"></A><BR></P></DIV>
<A NAME="Heading244"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Collections</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To summarize what we&#8217;ve seen
so far, your first, most efficient choice to hold a group of objects should be
an array, and you&#8217;re forced into this choice if you want to hold a group
of primitives. In the remainder of the chapter we&#8217;ll look at the more
general case, when you don&#8217;t know at the time you&#8217;re writing the
program how many objects you&#8217;re going to need, or if you need a more
sophisticated way to store your objects. Java provides four types of
<A NAME="Index738"></A><I>collection classes</I> to solve this problem:
<A NAME="Index739"></A><B>Vector</B>, <A NAME="Index740"></A><B>BitSet</B>,<B>
<A NAME="Index741"></A>Stack</B>, and <A NAME="Index742"></A><B>Hashtable</B>.
Although compared to other languages that provide collections this is a fairly
meager supply, you can nonetheless solve a surprising number of problems using
these tools.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Among their other characteristics
&#8211; <B>Stack</B>, for example, implements a LIFO (last-in, first-out)
sequence, and <B>Hashtable</B> is an <A NAME="Index743"></A><I>associative
array</I> that lets you associate any object with any other object &#8211; the
Java collection classes will automatically resize themselves. Thus, you can put
in any number of objects and you don&#8217;t need to worry about how big to make
the collection while you&#8217;re writing the
program.</FONT><A NAME="_Ref348399494"></A><A NAME="_Toc375545351"></A><A NAME="_Toc408018567"></A><BR></P></DIV>
<A NAME="Heading245"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Disadvantage: unknown type</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The &#8220;disadvantage&#8221; to
using the Java collections is that you lose type information when you put an
object into a collection. This happens because, when the collection was written,
the programmer of that collection had no idea what specific type you wanted to

⌨️ 快捷键说明

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