Chapter 11: Collections of Objects 下面的例子演示了如何返回一个 String数组: //: c11: IceCream. java Returning arrays from methods import com. bruceeckel. simpletest. import java.util.*i ublic class IceCream private static Test monitor new Test( private static Random rand new Random( public static final String[] flavors = f "Chocolate","Strawberry","Vanilla Fudge Swirl" "Mint Chip","Mocha Almond Fudge","Rum Raisin Praline Cream"Mud Pie" public static String[] flavorset (int n)( String[] results new String [n] boolean[] picked new boolean[flavors.length]i nt 0;i i++){ int t t = rand. nextInt(flavors. length while (picked[t])i results [i] s[t]; picked[t] true; return results public static void main (String[] args) t System. out. println "flavorset("+ 1+)=") String[] fl = flavorSet(flavors. length)i for (int 3=0;3< fl length 3++) System. out. println("\t"+ fl[jl)i monitor. expect (new object[] 号f1 avorset\(\\d+) \\t(chocolate l Strawberry l +"Vanilla Fudge SwirllMint Chip Mocha Almond # +"Fudge I Rum Raisin l Praline Cream I Mud flavorset()创建了一个名为 results的 String数组。这个数组的 容量是由传给它的参数n所决定的。接下来它从 flavors数组里面随机 选择 flavors(译者注:表示冰激凌的口味),放到 results中,最后返回 results。返回数组跟返回对象没什么两样——都是一个 reference。因 此数组是不是在 flavorset()或是其他什么地方创建的并不重要。只要 第6页共106页 www.wgqqh.com/shhgs/tij.html
Chapter 11: Collections of Objects 第 6 页 共 106 页 www.wgqqh.com/shhgs/tij.html email:shhgs@sohu.com 下面的例子演示了如何返回一个 String 数组: //: c11:IceCream.java // Returning arrays from methods. import com.bruceeckel.simpletest.*; import java.util.*; public class IceCream { private static Test monitor = new Test( ); private static Random rand = new Random( ); public static final String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; public static String[] flavorSet(int n) { String[] results = new String[n]; boolean[] picked = new boolean[flavors.length]; for(int i = 0; i < n; i++) { int t; do t = rand.nextInt(flavors.length); while(picked[t]); results[i] = flavors[t]; picked[t] = true; } return results; } public static void main(String[] args) { for(int i = 0; i < 20; i++) { System.out.println( "flavorSet(" + i + ") = "); String[] fl = flavorSet(flavors.length); for(int j = 0; j < fl.length; j++) System.out.println("\t" + fl[j]); monitor.expect(new Object[] { "%% flavorSet\\(\\d+\\) = ", new TestExpression("%% \\t(Chocolate|Strawberry|" + "Vanilla Fudge Swirl|Mint Chip|Mocha Almond " + "Fudge|Rum Raisin|Praline Cream|Mud Pie)", 8) }); } } } ///:~ flavorSet( ) 创建了一个名为 results 的 String 数组。这个数组的 容量是由传给它的参数 n 所决定的。接下来它从 flavors 数组里面随机 选择 flavors(译者注:表示冰激凌的口味),放到 results 中,最后返回 results。返回数组跟返回对象没什么两样——都是一个 reference。因 此数组是不是在 flavorSet( )或是其他什么地方创建的并不重要。只要
Thinking in Java 3Edition 你还需要,它就不会消失:一旦你用完了,垃圾回收器负责帮你收拾干 再附带说一下, flayorset()随机选择 flavors的时候,会检查那个 flavor以前是不是没被选中过。这是由do循环做的。它不断的作随机选 择,直到找到一个在 picked数组中还没有的。(当然,也可以用“比较 String”的方式来检查随机选出的 flavor是不是已经在 results数组中 了。)如果成功,它会添加这条记录,然后寻找下一个(递增ⅱ)。 main()会打印出20套 flavors,这样你就能看到,每次 flayorset() 都是随机选择 flavors的。如果把输出导到文件你就能看得更清楚。只是 记着看文件的时候,你只是想挑一个而不是真的想吃冰激凌。 Arrays类 java.util里面有一个 Arrays类,它包括了一组可用于数组的 static 方法,这些方法都是一些实用工具。其中有四个基本方法:用来比较两个 数组是否相等的 equals():用来填充数组的f():用来对数组进行 排序的sort():以及用于在一个已排序的数组中查找元素的 binarysearch()。所有这些方法都对 primitive和 Object进行了重 载。此外还有一个 aslist()方法,它接受一个数组,然后把它转成一个 List容器。后面你会学到。 虽然Aays还是有用的,但它的功能并不完整。举例来说,如果它能让 我们不用写for循环就能直接打印数组,那就好了。此外,正如你所看到 的,fl()只能用一个值填数组。所以,如果如果你想把随机生成的数字 填进数组的话,f)是无能为力的 因此为 Arrays类提供一些额外的功能还是有意义的。为方便起鉴,我把 它放到 package com. bruceeckelutil里。它可以打印任何类型的 数组;并且用“你定义的 generator对象生成的”值或对象填充一个数 组 由于要为各种 primitive以及 Object服务,程序里有大量的几乎是重复 的代码。3比如,next()必须根据不同的情况返回不同的类型,所以每 种类型都需要一个“ generator”接口。 //: com: bruceeckel: util: Generator. java package com. bruceeckel util; ublic interface Generator object next( )i)///: C++的程序员会觉得,如果能用默认参数和模板的话,可以少写很多代码。而 Python的程序员则会认 为,这个类库本身就是多余的 第7页共106页 www.wgqqh.com/shhgs/tij.html emailshhgsasohu.com
Thinking in Java 3rd Edition 第 7 页 共 106 页 www.wgqqh.com/shhgs/tij.html email:shhgs@sohu.com 你还需要,它就不会消失;一旦你用完了,垃圾回收器负责帮你收拾干 净。 再附带说一下,flavorSet( )随机选择 flavors 的时候,会检查那个 flavor 以前是不是没被选中过。这是由 do 循环做的。它不断的作随机选 择,直到找到一个在 picked 数组中还没有的。(当然,也可以用“比较 String”的方式来检查随机选出的 flavor 是不是已经在 results 数组中 了。)如果成功,它会添加这条记录,然后寻找下一个(递增 i)。 main( )会打印出 20 套 flavors,这样你就能看到,每次 flavorSet( ) 都是随机选择 flavors 的。如果把输出导到文件你就能看得更清楚。只是 记着看文件的时候,你只是想挑一个而不是真的想吃冰激凌。 Arrays 类 java.util 里面有一个 Arrays 类,它包括了一组可用于数组的 static 方法,这些方法都是一些实用工具。其中有四个基本方法:用来比较两个 数组是否相等的 equals( );用来填充数组的 fill( );用来对数组进行 排序的 sort( );以及用于在一个已排序的数组中查找元素的 binarySearch( )。所有这些方法都对 primitive 和 Object 进行了重 载。此外还有一个 asList( )方法,它接受一个数组,然后把它转成一个 List 容器。后面你会学到。 虽然 Arrays 还是有用的,但它的功能并不完整。举例来说,如果它能让 我们不用写 for 循环就能直接打印数组,那就好了。此外,正如你所看到 的,fill( )只能用一个值填数组。所以,如果如果你想把随机生成的数字 填进数组的话,fill( )是无能为力的。 因此为 Arrays 类提供一些额外的功能还是有意义的。为方便起鉴,我把 它放到 package com.bruceeckel.util 里。它可以打印任何类型的 数组;并且用“你定义的 generator 对象生成的”值或对象填充一个数 组。 由于要为各种 primitive 以及 Object 服务,程序里有大量的几乎是重复 的代码。3比如,next( )必须根据不同的情况返回不同的类型,所以每 种类型都需要一个“generator” 接口。 //: com:bruceeckel:util:Generator.java package com.bruceeckel.util; public interface Generator { Object next( ); } ///:~ 3 C++的程序员会觉得,如果能用默认参数和模板的话,可以少写很多代码。而 Python 的程序员则会认 为,这个类库本身就是多余的
Chapter 11: Collections of Objects //: com: bruceeckel: util: BooleanGenerator java package com. bruceeckel util; public interface BooleanGenerator i boolean next();)/// //: com: bruceeckel: util: ByteGenerator java package com. bruceeckelutili public interface ByteGenerator i byte next( )i) ///: //: com: bruceeckel: util: CharGenerator java package com. bruceeckel.util; public interface CharGenerator i char next( )i ///:~ //: com: bruceeckel: util: ShortGenerator java package com. bruceeckelut public interface ShortGenerator short next( )i 1 ///:~ 77: com: bruceeckel: util: IntGenerator java package com. bruceeckel util public interface IntGenerator i int next( );)/// //: com: bruceeckel: util: LongGenerator java package com. bruceeckel util blic inter //: com: bruceeckel: util: FloatGenerator java package bruceeckel utili oublic interface FloatGenerator float next()i ///:~ //: com: bruceeckel: util: DoubleGenerator java package com. bruceeckeluti public interface DoubleGenerator i double next()i j 第8页共106页 www.wgqqh.com/shhgs/tij.html
Chapter 11: Collections of Objects 第 8 页 共 106 页 www.wgqqh.com/shhgs/tij.html email:shhgs@sohu.com //: com:bruceeckel:util:BooleanGenerator.java package com.bruceeckel.util; public interface BooleanGenerator { boolean next( ); } ///:~ //: com:bruceeckel:util:ByteGenerator.java package com.bruceeckel.util; public interface ByteGenerator { byte next( ); } ///:~ //: com:bruceeckel:util:CharGenerator.java package com.bruceeckel.util; public interface CharGenerator { char next( ); } ///:~ //: com:bruceeckel:util:ShortGenerator.java package com.bruceeckel.util; public interface ShortGenerator { short next( ); } ///:~ //: com:bruceeckel:util:IntGenerator.java package com.bruceeckel.util; public interface IntGenerator { int next( ); } ///:~ //: com:bruceeckel:util:LongGenerator.java package com.bruceeckel.util; public interface LongGenerator { long next( ); } ///:~ //: com:bruceeckel:util:FloatGenerator.java package com.bruceeckel.util; public interface FloatGenerator { float next( ); } ///:~ //: com:bruceeckel:util:DoubleGenerator.java package com.bruceeckel.util; public interface DoubleGenerator { double next( ); } ///:~
Thinking in Java 3Edition Arrays2包含了很多 tostring()方法以重载各种类型。这些方法能让 你很方便地打印出一个数组。 tostring()方法用了 String Buffer而 不是 String对象。这是出于运行效率的考虑;当你需要重复调用一个方 法以组装字符串的时候,较为明智的选择还是使用效率更高的 String Buffer,而不是更方便的 String。这里,创建 String Buffer 的时候用了一个初始值,然后再它后面接 String。最后,把 result转 换成 String再返回 //: com: bruceeckel:util: Arrays2 java /A supplement to java. util. Arrays, to provide additional // useful functionality when working with arrays Allows // any array to be converted to a String, and to be filled // package com. bruceeckel util import java. util.*i public class Arrays public static string tostring(boolean[] a) String Buffer result new String Buffer("[")i for (int i =0; i<alength; 1++) result. append(a[i])i if(i a length-1 y result. append(",) ult append("]") urn result. tostring()i public static string tostring(byte[] a) StringBuffer result new StringBuffer("[") 0; i <a length; i++)t result. append(a[i])i if(i a length -1) result. append(",")i result public static string tostring(char [ a)( StringBuffer result new StringBuffer("[")i for (int i =0 result. append(a[])i if (i alength -1) appe return result. tostring( public static String tostring(short[ a)i ew stringBu for (int i =0; i<alength; 1++) result. append(a[i])i if(i a length -1) result. append(",")i 第9页共106页 www.wgqqh.com/shhgs/tij.html
Thinking in Java 3rd Edition 第 9 页 共 106 页 www.wgqqh.com/shhgs/tij.html email:shhgs@sohu.com Arrays2 包含了很多 toString( )方法以重载各种类型。这些方法能让 你很方便地打印出一个数组。toString( )方法用了 StringBuffer 而 不是 String 对象。这是出于运行效率的考虑;当你需要重复调用一个方 法以组装字符串的时候,较为明智的选择还是使用效率更高的 StringBuffer,而不是更方便的 String。这里,创建 StringBuffer 的时候用了一个初始值,然后再它后面接 String。最后,把 result 转 换成 String 再返回: //: com:bruceeckel:util:Arrays2.java // A supplement to java.util.Arrays, to provide additional // useful functionality when working with arrays. Allows // any array to be converted to a String, and to be filled // via a user-defined "generator" object. package com.bruceeckel.util; import java.util.*; public class Arrays2 { public static String toString(boolean[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(byte[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(char[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(short[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); }
Chapter 11: Collections of Objects result. append( "]")i eturn result. tostring( public static string tostring (int[] a)i StringBuffer result new StringBuffer("[")i for (int i = 0; i<alength; i++) result. append(a [i])i if (i a length -1 result. append(,)i result. append("]") return result. tostring( )i public static String tostring (long[] a)( StringBuffer result new StringBuffer("[") for(int i =0; i<a length; i++)t result. append(a[i]) if(i a length -1) result. append(",")i result return result. tostring( )i public static String tostring(float[ a) StringBuffer result new StringBuffer("[") for(int i =0; i<a length; 1++) (a[i]); if (i alength -1 result. append(,)i result. append("]")i public static string tostring(double [] a) StringBuffer result new String Buffer("[")i for (int i =0; i<alength; 1++) result. append(a[i])i f(i< al 1) (","); result. append("]") // Fill an array using a generator: public static void fill(object a.⊥eng public static void fill(object[] a, int from, int to, Generator gen for (int i = from; i< a lil public static void fill(boolean[ a, BooleanGenerator gen) t blic static void 第10页共106页 wgqqh. com/shhgs/tij. html
Chapter 11: Collections of Objects 第 10 页 共 106 页 www.wgqqh.com/shhgs/tij.html email:shhgs@sohu.com result.append("]"); return result.toString( ); } public static String toString(int[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(long[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(float[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } public static String toString(double[] a) { StringBuffer result = new StringBuffer("["); for(int i = 0; i < a.length; i++) { result.append(a[i]); if(i < a.length - 1) result.append(", "); } result.append("]"); return result.toString( ); } // Fill an array using a generator: public static void fill(Object[] a, Generator gen) { fill(a, 0, a.length, gen); } public static void fill(Object[] a, int from, int to, Generator gen) { for(int i = from; i < to; i++) a[i] = gen.next( ); } public static void fill(boolean[] a, BooleanGenerator gen) { fill(a, 0, a.length, gen); } public static void