📄 tij313.htm
字号:
<p>In many situations this syntax provides a more convenient way to write code. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1259" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The expression:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>a = d;</PRE></FONT></BLOCKQUOTE><p><br></p>
<p>shows how you can take a reference that’s attached to one array object and assign it to another array object, just as you can do with any other type of object reference. Now both <b>a</b> and <b>d</b> are pointing to the same array object on the heap. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1260" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>The second part of <b>ArraySize.java</b> shows that primitive arrays work just like object arrays <i>except</i> that primitive arrays hold the primitive values directly. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1261" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h4>
<a name="_Toc375545349"></a><a name="Heading10284"></a>Containers of
primitives<br></h4>
<p><a name="Index974"></a><a name="Index975"></a>Container classes can hold only references to <b>Object</b>s. An array, however, can be created to hold primitives directly, as well as references to <b>Object</b>s. It <i>is</i> possible to use the “wrapper” classes, such as <b>Integer</b>, <b>Double</b>, etc., to place primitive values inside a container, but the wrapper classes for primitives can be awkward to use. In addition, it’s much more efficient to create and access an array of primitives than a container of wrapped primitives. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1262" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Of course, if you’re using a primitive type and you need the flexibility of a container that automatically expands when more space is needed, the array won’t work, and you’re forced to use a container of wrapped primitives. You might think that there should be a specialized type of <b>ArrayList</b> for each of the primitive data types, but Java doesn’t provide this for you.<sup><a name="fnB52" href="#fn52">[52]</a></sup> <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1263" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775736"></a><a name="Heading10288"></a>Returning an array</h3>
<p>Suppose you’re writing a method and you don’t just want to return just one thing, but a whole bunch of things. Languages like C and C++ make this difficult because you can’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 size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1264" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index976"></a><a name="Index977"></a>Java takes a similar approach, but you just “return an array.” Unlike C++, with Java you never worry about responsibility for that array—it will be around as long as you need it, and the garbage collector will clean it up when you’re done. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1265" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>As an example, consider returning an array of <b>String</b>:<br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c11:IceCream.java</font>
<font color=#009900>// Returning arrays from methods.</font>
<font color=#0000ff>import</font> com.bruceeckel.simpletest.*;
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> IceCream {
<font color=#0000ff>private</font> <font color=#0000ff>static</font> Test monitor = <font color=#0000ff>new</font> Test();
<font color=#0000ff>private</font> <font color=#0000ff>static</font> Random rand = <font color=#0000ff>new</font> Random();
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>final</font> String[] flavors = {
<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>public</font> <font color=#0000ff>static</font> String[] flavorSet(<font color=#0000ff>int</font> n) {
String[] results = <font color=#0000ff>new</font> String[n];
<font color=#0000ff>boolean</font>[] picked = <font color=#0000ff>new</font> <font color=#0000ff>boolean</font>[flavors.length];
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < n; i++) {
<font color=#0000ff>int</font> t;
<font color=#0000ff>do</font>
t = rand.nextInt(flavors.length);
<font color=#0000ff>while</font>(picked[t]);
results[i] = flavors[t];
picked[t] = <font color=#0000ff>true</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 < 20; i++) {
System.out.println(
<font color=#004488>"flavorSet("</font> + i + <font color=#004488>") = "</font>);
String[] fl = flavorSet(flavors.length);
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> j = 0; j < fl.length; j++)
System.out.println(<font color=#004488>"\t"</font> + fl[j]);
monitor.expect(<font color=#0000ff>new</font> Object[] {
<font color=#004488>"%% flavorSet\\(\\d+\\) = "</font>,
<font color=#0000ff>new</font> TestExpression(<font color=#004488>"%% \\t(Chocolate|Strawberry|"</font>
+ <font color=#004488>"Vanilla Fudge Swirl|Mint Chip|Mocha Almond "</font>
+ <font color=#004488>"Fudge|Rum Raisin|Praline Cream|Mud Pie)"</font>, 8)
});
}
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p>The method <b>flavorSet( )</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 that you pass into the method. Then it proceeds to choose flavors randomly from the array <b>flavors</b> and place them into <b>results</b>, which it finally returns. Returning an array is just like returning any other object—it’s a reference. It’s not important that the array was created within <b>flavorSet( )</b>, or that the array was created anyplace else, for that matter. The garbage collector takes care of cleaning up the array when you’re done with it, and the array will persist for as long as you need it. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1266" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>As an aside, notice that when <b>flavorSet( )</b> chooses flavors randomly, it ensures that a particular choice hasn’t already been selected. This is performed in a <b>do</b> loop that keeps making random choices until it finds one not already in the <b>picked</b> array. (Of course, a <b>String</b> comparison also could have been performed to see if the random choice was already in the <b>results</b> array.) If it’s successful, it adds the entry and finds the next one (<b>i </b>gets incremented). <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1267" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><b>main( )</b> prints out 20 full sets of flavors, so you can see that <b>flavorSet( )</b> chooses the flavors in a random order each time. It’s easiest to see this if you redirect the output into a file. And while you’re looking at the file, remember that you just <i>want</i> the ice cream, you don’t <i>need</i> it. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1268" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h3>
<a name="_Toc24775737"></a><a name="Heading10338"></a>The <b>Arrays</b>
class</h3>
<p>In <b>java.util</b>, you’ll find the <a name="Index978"></a><b>Arrays</b> class, which holds a set of <b>static</b> methods that perform utility functions for arrays. There are four basic methods: <b>equals( )</b>, to compare two arrays for equality; <b>fill( )</b>, to fill an array with a value; <b>sort( )</b>, to sort the array; and <b>binarySearch( )</b>, to find an element in a sorted array. All of these methods are overloaded for all the primitive types and <b>Object</b>s. In addition, there’s a single <b>asList( )</b> method that takes any array and turns it into a <b>List</b> container, which you’ll learn about later in this chapter. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1269" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Although useful, the <b>Arrays</b> class stops short of being fully functional. For example, it would be nice to be able to easily print the elements of an array without having to code a <b>for</b> loop by hand every time. And as you’ll see, the <b>fill( )</b> method only takes a single value and places it in the array, so if you wanted, for example, to fill an array with randomly generated numbers, <b>fill( )</b> is no help. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1270" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p>Thus it makes sense to supplement the <b>Arrays</b> class with some additional utilities, which will be placed in the <b>package</b> <b>com.bruceeckel.util</b> for convenience. These will print an array of any type and fill an array with values or objects that are created by an object called a <i>generator</i> that you can define. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]Chap09_1271" title="Send BackTalk Comment">Feedback</a></font><br></p>
<p><a name="Index979"></a>Because code needs to be created for each primitive type as well as <b>Object</b>, there’s a lot of nearly duplicated code.<sup><a name="fnB53" href="#fn53">[53]</a></sup> For example, a “generator” interface is required for each type because the return type of <b>next( )</b> must be different in each case: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0125" title="Send BackTalk Comment">Feedback</a></font><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:Generator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> Generator { Object next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:BooleanGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> BooleanGenerator { <font color=#0000ff>boolean</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:ByteGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> ByteGenerator { <font color=#0000ff>byte</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:CharGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> CharGenerator { <font color=#0000ff>char</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:ShortGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> ShortGenerator { <font color=#0000ff>short</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:IntGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> IntGenerator { <font color=#0000ff>int</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:LongGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> LongGenerator { <font color=#0000ff>long</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:FloatGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> FloatGenerator { <font color=#0000ff>float</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:DoubleGenerator.java</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>interface</font> DoubleGenerator { <font color=#0000ff>double</font> next(); } <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE><p><br></p>
<p><a name="Index980"></a><b>Arrays2</b> contains a variety of <b>toString( )</b> methods, overloaded for each type. These methods allow you to easily print an array. The <b>toString( )</b> code introduces the use of <b>StringBuffer</b> instead of <b>String</b> objects. This is a nod to efficiency; when you’re assembling a string in a method that might be called a lot, it’s wiser to use the more efficient <b>StringBuffer</b> rather than the more convenient <b>String</b> operations. Here, the <b>StringBuffer</b> is created with an initial value, and <b>Strings</b> are appended. Finally, the <b>result</b> is converted to a <b>String</b> as the return value: <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]A0126" title="Send BackTalk Comment">Feedback</a></font><br></p>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:util:Arrays2.java</font>
<font color=#009900>// A supplement to java.util.Arrays, to provide additional</font>
<font color=#009900>// useful functionality when working with arrays. Allows</font>
<font color=#009900>// any array to be converted to a String, and to be filled</font>
<font color=#009900>// via a user-defined "generator" object.</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>import</font> java.util.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Arrays2 {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> String toString(<font color=#0000ff>boolean</font>[] a) {
StringBuffer result = <font color=#0000ff>new</font> StringBuffer(<font color=#004488>"["</font>);
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < a.length; i++) {
result.append(a[i]);
<font color=#0000ff>if</font>(i < a.length - 1)
result.append(<font color=#004488>", "</font>);
}
result.append(<font color=#004488>"]"</font>);
<font color=#0000ff>return</font> result.toString();
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> String toString(<font color=#0000ff>byte</font>[] a) {
StringBuffer result = <font color=#0000ff>new</font> StringBuffer(<font color=#004488>"["</font>);
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < a.length; i++) {
result.append(a[i]);
<font color=#0000ff>if</font>(i < a.length - 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -