八宝书库 > 文学其他电子书 > Java编程思想第4版[中文版](PDF格式) >

第71部分

Java编程思想第4版[中文版](PDF格式)-第71部分

小说: Java编程思想第4版[中文版](PDF格式) 字数: 每页4000字

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




对所有操作的支持。但是,如果想新建一个集合,同时不想为集合接口中的所有方法都提供有意义的定义, 

同时令其仍与现有库配合,这种设计方法也确实提供了一个“后门”可以利用。  

(2) 若一个操作未获支持,那么UnsupportedOperationException (未支持的操作违例)极有可能在实现期 

间出现,则不是在产品已交付给客户以后才会出现。它毕竟指出的是一个编程错误——不正确地使用了一个 

类。这一点不能十分确定,通过也可以看出这种方案的“试验”特征——只有经过多次试验,才能找出最理 

想的工作方式。  

  

在上面的例子中,Arrays。toList()产生了一个 List (列表),该列表是由一个固定长度的数组后推出来 

的。因此唯一能够支持的就是那些不改变数组长度的操作。在另一方面,若请求一个新接口表达不同种类的 

行为(可能叫作“FixedSizeList ”——固定长度列表),就有遭遇更大的复杂程度的危险。这样一来,以后 

试图使用库的时候,很快就会发现自己不知从何处下手。  

对那些采用 Collection,List,Set 或者Map 作为参数的方法,它们的文档应当指出哪些可选的方法是必须 

实现的。举个例子来说,排序要求实现set()和 Iterator。set()方法,但不包括add()和 remove() 。  



8。7。7  排序和搜索  



Java 1。2 添加了自己的一套实用工具,可用来对数组或列表进行排列和搜索。这些工具都属于两个新类的 

 “静态”方法。这两个类分别是用于排序和搜索数组的Arrays,以及用于排序和搜索列表的Collections。  

  

1。 数组  

Arrays 类为所有基本数据类型的数组提供了一个过载的 sort()和 binarySearch(),它们亦可用于String 和 

Object。下面这个例子显示出如何排序和搜索一个字节数组(其他所有基本数据类型都是类似的)以及一个 

String 数组:  

  

//: Array1。java  

// Testing the sorting & searching in Arrays  

package c08。newcollections;  

import java。util。*;  

  

public class Array1 {  

  static Random r = new Random();  

  static String ssource =   

    〃ABCDEFGHIJKLMNOPQRSTUVWXYZ〃 +  

    〃abcdefghijklmnopqrstuvwxyz〃;  

  static char'' src = ssource。toCharArray();  

  // Create a random String  

  public static String randString(int length) {  

    char'' buf = new char'length';  

    int rnd;  

    for(int i = 0; i 《 length; i++) {  

      rnd = Math。abs(r。nextInt()) % src。length;  

      buf'i' = src'rnd';  

    }  

    return new String(buf);  

  }  

  // Create a random array of Strings:  

  public static   



                                                                                    255 


…………………………………………………………Page 257……………………………………………………………

  String'' randStrings(int length; int size) {  

    String'' s = new String'size';  

    for(int i = 0; i 《 size; i++)  

      s'i' = randString(length);  

    return s;  

  }  

  public static void print(byte'' b) {  

    for(int i = 0; i 《 b。length; i++)  

      System。out。print(b'i' + 〃 〃);  

    System。out。println();  

  }  

  public static void print(String'' s) {  

    for(int i = 0; i 《 s。length; i++)  

      System。out。print(s'i' + 〃 〃);  

    System。out。println();  

  }  

  public static void main(String'' args) {  

    byte'' b = new byte'15';  

    r。nextBytes(b); // Fill with random bytes  

    print(b);  

    Arrays。sort(b);  

    print(b);  

    int loc = Arrays。binarySearch(b; b'10');  

    System。out。println(〃Location of 〃 + b'10' +  

      〃 = 〃 + loc);  

    // Test String sort & search:  

    String'' s = randStrings(4; 10);  

    print(s);  

    Arrays。sort(s);  

    print(s);  

    loc = Arrays。binarySearch(s; s'4');  

    System。out。println(〃Location of 〃 + s'4' +  

      〃 = 〃 + loc);  

  }  

} ///:~  

  

类的第一部分包含了用于产生随机字串对象的实用工具,可供选择的随机字母保存在一个字符数组中。 

randString()返回一个任意长度的字串;而 readStrings()创建随机字串的一个数组,同时给定每个字串的 

长度以及希望的数组大小。两个print()方法简化了对示范数组的显示。在 main()中,Random。nextBytes() 

用随机选择的字节填充数组自变量(没有对应的Random 方法用于创建其他基本数据类型的数组)。获得一个 

数组后,便可发现为了执行sort()或者 binarySearch(),只需发出一次方法调用即可。与binarySearch() 

有关的还有一个重要的警告:若在执行一次binarySearch()之前不调用 sort(),便会发生不可预测的行为, 

其中甚至包括无限循环。  

对String 的排序以及搜索是相似的,但在运行程序的时候,我们会注意到一个有趣的现象:排序遵守的是字 

典顺序,亦即大写字母在字符集中位于小写字母的前面。因此,所有大写字母都位于列表的最前面,后面再 

跟上小写字母——Z 居然位于a 的前面。似乎连电话簿也是这样排序的。  

  

2。 可比较与比较器  

但假若我们不满足这一排序方式,又该如何处理呢?例如本书后面的索引,如果必须对以A 或a 开头的词条 

分别到两处地方查看,那么肯定会使读者颇不耐烦。  

若想对一个 Object 数组进行排序,那么必须解决一个问题。根据什么来判定两个 Object 的顺序呢?不幸的 

是,最初的 Java 设计者并不认为这是一个重要的问题,否则就已经在根类 Object 里定义它了。这样造成的 



                                                                                          256 


…………………………………………………………Page 258……………………………………………………………

一个后果便是:必须从外部进行Object 的排序,而且新的集合库提供了实现这一操作的标准方式(最理想的 

是在Object 里定义它)。  

针对Object 数组(以及 String,它当然属于Object 的一种),可使用一个 sort(),并令其接纳另一个参 

数:实现了 parator 接口(即“比较器”接口,新集合库的一部分)的一个对象,并用它的单个 

pare()方法进行比较。这个方法将两个准备比较的对象作为自己的参数使用——若第一个参数小于第二 

个,返回一个负整数;若相等,返回零;若第一个参数大于第二个,则返回正整数。基于这一规则,上述例 

子的String 部分便可重新写过,令其进行真正按字母顺序的排序:  

  

//: Alphap。java  

// Using parator to perform an alphabetic sort  

package c08。newcollections;  

import java。util。*;  

  

public class Alphap implements parator {  

  public int pare(Object o1; Object o2) {  

    // Assume it's used only for Strings。。。  

    String s1 = ((String)o1)。toLowerCase();  

    String s2 = ((String)o2)。toLowerCase();  

    return s1。pareTo(s2);  

  }  

  public static void main(String'' args) {  

    String'' s = Array1。randStrings(4; 10);  

    Array1。print(s);  

    Alphap ac = new Alphap();  

    Arrays。sort(s; ac);  

    Array1。print(s);  

    // Must use the parator to search; also:  

    int loc = Arrays。binarySearch(s; s'3'; ac);  

    System。out。println(〃Location of 〃 + s'3' +  

     〃 = 〃 + loc);  

  }  

} ///:~  

  

通过造型为 String,pare()方法会进行“暗示”性的测试,保证自己操作的只能是String 对象——运行 

期系统会捕获任何差错。将两个字串都强迫换成小写形式后,String。pareTo()方法会产生预期的结果。  

若用自己的 parator 来进行一次 sort(),那么在使用binarySearch()时必须使用那个相同的 

parator。  

Arrays 类提供了另一个 sort()方法,它会采用单个自变量:一个 Object 数组,但没有parator。这个 

sort()方法也必须用同样的方式来比较两个 Object。通过实现parable 接口,它采用了赋予一个类的 

 “自然比较方法”。这个接口含有单独一个方法——pareTo(),能分别根据它小于、等于或者大于自变量 

而返回负数、零或者正数,从而实现对象的比较。下面这个例子简单地阐示了这一点:  

  

//: pClass。java  

// A class that implements parable  

package c08。newcollections;  

import java。util。*;  

  

public class pClass implements parable {  

  private int i;  

  public pClass(int ii) { i = ii; }  

  public int pareTo(Object o) {  

    // Implicitly tests for correct type:  



                                                                                          257 


…………………………………………………………Page 259……………………………………………………………

    int argi = ((pClass)o)。i;  

    if(i == argi) return 0;  

    if(i 《 argi) return …1;  

    return 1;  

  }  

  public static void print(Object'' a) {  

    for(int i = 0; i 《 a。length; i++)  

      System。out。print(a'i' + 〃 〃);  

    System。out。println();  

  }  

  public String toString() { return i + 〃〃; }  

  public static void main(String'' args) {  

    pClass'' a = new pClass'20';  

    for(int i = 0; i 《 a。length; i++)  

      a'i' = new pClass(  

        (int)(Math。random() *100));  

    print(a);  

    Arrays。sort(a);  

    print(a);  

    int loc = Arrays。binarySearch(a; a'3');  

    System。out。println(〃Location of 〃 + a'3' +  

     〃 = 〃 + loc);  

  }  

} ///:~  

  

当然,我们的 pareTo()方法亦可根据实际情况增大复杂程度。  

  

3。 列表  

可用与数组相同的形式排序和搜索一个列表(List )。用于排序和搜索列表的静态方法包含在类 

Collections 中,但它们拥有与Arrays 中差不多的签名:sort(List)用于对一个实现了 parable 的对象 

列表进行排序;binarySearch(List;Object)用于查找列表中的某个对象;sort(List;parator)利用一个 

 “比较器”对一个列表进行排序;而binarySearch(List;Object;parator)则用于查找那个列表中的一个 

对象(注释⑨)。下面这个例子利用了预先定义好的pClass 和 Alphap 来示范 Collections 中的各种 

排序工具:  

  

//: ListSort。java  

// Sorting and searching Lists with 'Collections'  

package c08。newcollections;  

import java。util。*;  

  

public class ListSort {  

  public static void main(String'' args) {   

    final int SZ = 20;  

    // Using 〃natural parison method〃:  

    List a = new ArrayList();  

    for(int i = 0; i 《 SZ; i++)  

      a。add(new pClass(  

        (int)(Math。random() *100)));  

    Collection1。print(a);  

    Collections。sort(a);  

    Collection1。print(a);  

    Object find = a。get(SZ/2);  



                                                                                          258 


…………………………………………………………Page 260……………………………………………………………

    int loc = Collections。binarySearch(a; find);  

    System。out。println(〃Location of 〃 + find +  

     〃 = 〃 + loc);  

    // Using a parator:  

    List b = new ArrayList();  

    for(int i = 0; i 《 SZ; i++)  

      b。add(Array1。randString(4));  

    Collection1。print(b);  

    Alphap ac = new Alphap();  

    Collections。sort(b; ac);  

    Collection1。print(b);  

    find = b。get(SZ/2);  

    // Must use the parator to search; also:  

    loc = Collections。binarySearch(b; find; ac);  

    System。out。println(〃Location of 〃 + find +  

     〃 = 〃 + loc);  

  }  

} ///:~  

  

⑨:在本书写作时,已宣布了一个新的Collections。stabl

返回目录 上一页 下一页 回到顶部 0 1

你可能喜欢的