友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第88章

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




果需要创建大量Map,而且只有在以后才需要涉及大量检索操作,那么最佳的策略就是:创建和填充 

TreeMap;以后检索量增大的时候,再将重要的TreeMap 转换成HashMap——使用HashMap(Map)构建器。同样 

地,只有在事实证明确实存在性能瓶颈后,才应关心这些方面的问题——先用起来,再根据需要加快速度。  



8。7。6  未支持的操作  



利用 static (静态)数组Arrays。toList(),也许能将一个数组转换成List,如下所示:  

  

//: Unsupported。java  

// Sometimes methods defined in the Collection  

// interfaces don't work!  

package c08。newcollections;  

import java。util。*;  

  

public class Unsupported {  

  private static String'' s = {  



                                                                                          253 


…………………………………………………………Page 255……………………………………………………………

    〃one〃; 〃two〃; 〃three〃; 〃four〃; 〃five〃;  

    〃six〃; 〃seven〃; 〃eight〃; 〃nine〃; 〃ten〃;  

  };  

  static List a = Arrays。toList(s);  

  static List a2 = Arrays。toList(  

    new String'' { s'3'; s'4'; s'5' });  

  public static void main(String'' args) {  

    Collection1。print(a); // Iteration  

    System。out。println(  

      〃a。contains(〃 + s'0' + 〃) = 〃 +   

      a。contains(s'0'));  

    System。out。println(  

      〃a。containsAll(a2) = 〃 +   

      a。containsAll(a2));  

    System。out。println(〃a。isEmpty() = 〃 +  

      a。isEmpty());  

    System。out。println(  

      〃a。indexOf(〃 + s'5' + 〃) = 〃 +   

      a。indexOf(s'5'));  

    // Traverse backwards:  

    ListIterator lit = a。listIterator(a。size());  

    while(lit。hasPrevious())  

      System。out。print(lit。previous());  

    System。out。println();  

    // Set the elements to different values:  

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

      a。set(i; 〃47〃);  

    Collection1。print(a);  

    // piles; but won't run:  

    lit。add(〃X〃); // Unsupported operation  

    a。clear(); // Unsupported  

    a。add(〃eleven〃); // Unsupported  

    a。addAll(a2); // Unsupported  

    a。retainAll(a2); // Unsupported  

    a。remove(s'0'); // Unsupported  

    a。removeAll(a2); // Unsupported  

  }  

} ///:~  

  

从中可以看出,实际只实现了 Collection 和 List 接口的一部分。剩余的方法导致了不受欢迎的一种情况, 

名为UnsupportedOperationException。在下一章里,我们会讲述违例的详细情况,但在这里有必要进行一 

下简单说明。这里的关键在于“集合接口”,以及新集合库内的另一些接口,它们都包含了“可选的”方 

法。在实现那些接口的集合类中,或者提供、或者没有提供对那些方法的支持。若调用一个未获支持的方 

法,就会导致一个UnsupportedOperationException (操作未支持违例),这表明出现了一个编程错误。  

大家或许会觉得奇怪,不是说“接口”和基础类最大的“卖点”就是它们许诺这些方法能产生一些有意义的 

行为吗?上述违例破坏了那个许诺——它调用的一部分方法不仅不能产生有意义的行为,而且还会中止程序 

的运行。在这些情况下,类型的所谓安全保证似乎显得一钱不值!但是,情况并没有想象的那么坏。通过 

Collection,List,Set 或者Map,编译器仍然限制我们只能调用那个接口中的方法,所以它和 Smalltalk 还 

是存在一些区别的(在 Smalltalk 中,可为任何对象调用任何方法,而且只有在运行程序时才知道这些调用 

是否可行)。除此以外,以Collection 作为自变量的大多数方法只能从那个集合中读取数据——Collection 

的所有“read ”方法都不是可选的。  

这样一来,系统就可避免在设计期间出现接口的冲突。而在集合库的其他设计方案中,最终经常都会得到数 



                                                                                          254 


…………………………………………………………Page 256……………………………………………………………

量过多的接口,用它们描述基本方案的每一种变化形式,所以学习和掌握显得非常困难。有些时候,甚至难 

于捕捉接口中的所有特殊情况,因为人们可能设计出任何新接口。但 Java 的“不支持的操作”方法却达到了 

新集合库的一个重要设计目标:易于学习和使用。但是,为了使这一方法真正有效,却需满足下述条件:  

(1) UnsupportedOperationException必须属于一种“非常”事件。也就是说,对于大多数类来说,所有操 

作都应是可行的。只有在一些特殊情况下,一、两个操作才可能未获支持。新集合库满足了这一条件,因为 

绝大多数时候用到的类——ArrayList,LinkedList,HashList 和 HashMap,以及其他集合方案——都提供了 

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

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

(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() 

有关的还有一个重要的警告:若在
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!