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

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

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




堆栈就会溢出,同时违例控制机制根本没有机会作出响应。  

若确实想在这种情况下打印出对象的地址,解决方案就是调用 Object 的 toString 方法。此时就不必加入 

this,只需使用 super。toString()。当然,采取这种做法也有一个前提:我们必须从 Object 直接继承,或 

者没有一个父类覆盖了 toString 方法。  



                                                                                  220 


…………………………………………………………Page 222……………………………………………………………

8。4。2 BitSet  



BitSet 实际是由“二进制位”构成的一个 Vector。如果希望高效率地保存大量“开-关”信息,就应使用 

BitSet。它只有从尺寸的角度看才有意义;如果希望的高效率的访问,那么它的速度会比使用一些固有类型 

的数组慢一些。  

此外,BitSet 的最小长度是一个长整数(Long )的长度:64 位。这意味着假如我们准备保存比这更小的数 

据,如 8 位数据,那么 BitSet 就显得浪费了。所以最好创建自己的类,用它容纳自己的标志位。  

在一个普通的Vector 中,随我们加入越来越多的元素,集合也会自我膨胀。在某种程度上,BitSet 也不例 

外。也就是说,它有时会自行扩展,有时则不然。而且Java 的1。0 版本似乎在这方面做得最糟,它的 

BitSet 表现十分差强人意(Java1。1 已改正了这个问题)。下面这个例子展示了BitSet 是如何运作的,同时 

演示了 1。0 版本的错误:  

  

//: Bits。java  

// Demonstration of BitSet  

import java。util。*;  

  

public class Bits {  

  public static void main(String'' args) {  

    Random rand = new Random();  

    // Take the LSB of nextInt():  

    byte bt = (byte)rand。nextInt();  

    BitSet bb = new BitSet();  

    for(int i = 7; i 》=0; i……)  

      if(((1 =0; i……)  

      if(((1 =0; i……)  

      if(((1 = 64 bits:  

    BitSet b127 = new BitSet();  

    b127。set(127);  



                                                                                          221 


…………………………………………………………Page 223……………………………………………………………

    System。out。println(〃set bit 127: 〃 + b127);  

    BitSet b255 = new BitSet(65);  

    b255。set(255);  

    System。out。println(〃set bit 255: 〃 + b255);  

    BitSet b1023 = new BitSet(512);  

// Without the following; an exception is thrown  

// in the Java 1。0 implementation of BitSet:  

//    b1023。set(1023);  

    b1023。set(1024);  

    System。out。println(〃set bit 1023: 〃 + b1023);  

  }  

  static void printBitSet(BitSet b) {  

    System。out。println(〃bits: 〃 + b);  

    String bbits = new String();  

    for(int j = 0; j 《 b。size() ; j++)  

      bbits += (b。get(j) ? 〃1〃 : 〃0〃);  

    System。out。println(〃bit pattern: 〃 + bbits);  

  }  

} ///:~  

  

随机数字生成器用于创建一个随机的byte、short 和 int。每一个都会转换成BitSet 内相应的位模型。此时 

一切都很正常,因为BitSet 是64 位的,所以它们都不会造成最终尺寸的增大。但在 Java 1。0 中,一旦 

BitSet 大于64 位,就会出现一些令人迷惑不解的行为。假如我们设置一个只比BitSet 当前分配存储空间大 

出1 的一个位,它能够正常地扩展。但一旦试图在更高的位置设置位,同时不先接触边界,就会得到一个恼 

人的违例。这正是由于 BitSet 在 Java 1。0 里不能正确扩展造成的。本例创建了一个 512 位的BitSet。构建 

器分配的存储空间是位数的两倍。所以假如设置位 1024 或更高的位,同时没有先设置位 1023,就会在Java  

1。0里得到一个违例。但幸运的是,这个问题已在 Java 1。1 得到了改正。所以如果是为Java 1。0 写代码, 

请尽量避免使用BitSet。  



8。4。3 Stack  



Stack 有时也可以称为“后入先出”(LIFO )集合。换言之,我们在堆栈里最后“压入”的东西将是以后第 

一个“弹出”的。和其他所有 Java 集合一样,我们压入和弹出的都是“对象”,所以必须对自己弹出的东西 

进行“造型”。  

一种很少见的做法是拒绝使用Vector 作为一个Stack 的基本构成元素,而是从Vector 里“继承”一个 

Stack。这样一来,它就拥有了一个Vector 的所有特征及行为,另外加上一些额外的Stack 行为。很难判断 

出设计者到底是明确想这样做,还是属于一种固有的设计。  

下面是一个简单的堆栈示例,它能读入数组的每一行,同时将其作为字串压入堆栈。  

  

//: Stacks。java  

// Demonstration of Stack Class  

import java。util。*;  

  

public class Stacks {  

  static String'' months = {   

    〃January〃; 〃February〃; 〃March〃; 〃April〃;  

    〃May〃; 〃June〃; 〃July〃; 〃August〃; 〃September〃;  

    〃October〃; 〃November〃; 〃December〃 };  

  public static void main(String'' args) {  

    Stack stk = new Stack();  

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

      stk。push(months'i' + 〃 〃);  

    System。out。println(〃stk = 〃 + stk);  



                                                                                          222 


…………………………………………………………Page 224……………………………………………………………

    // Treating a stack as a Vector:  

    stk。addElement(〃The last line〃);  

    System。out。println(  

      〃element 5 = 〃 + stk。elementAt(5));  

    System。out。println(〃popping elements:〃);  

    while(!stk。empty())  

      System。out。println(stk。pop());  

  }  

} ///:~  

  

months 数组的每一行都通过 push()继承进入堆栈,稍后用 pop()从堆栈的顶部将其取出。要声明的一点是, 

Vector 操作亦可针对 Stack 对象进行。这可能是由继承的特质决定的——Stack “属于”一种Vector。因 

此,能对Vector 进行的操作亦可针对Stack 进行,例如 elementAt()方法。  



8。4。4 Hashtable  



Vector 允许我们用一个数字从一系列对象中作出选择,所以它实际是将数字同对象关联起来了。但假如我们 

想根据其他标准选择一系列对象呢?堆栈就是这样的一个例子:它的选择标准是“最后压入堆栈的东西”。 

这种“从一系列对象中选择”的概念亦可叫作一个“映射”、“字典”或者“关联数组”。从概念上讲,它 

看起来象一个Vector,但却不是通过数字来查找对象,而是用另一个对象来查找它们!这通常都属于一个程 

序中的重要进程。  

在Java 中,这个概念具体反映到抽象类Dictionary 身上。该类的接口是非常直观的 size()告诉我们其中包 

含了多少元素;isEmpty()判断是否包含了元素(是则为 true);put(Object key; Object value)添加一个 

值(我们希望的东西),并将其同一个键关联起来(想用于搜索它的东西);get(Object key)获得与某个键 

对应的值;而remove(Object Key)用于从列表中删除“键-值”对。还可以使用枚举技术:keys()产生对键 

的一个枚举(Enumeration);而 elements()产生对所有值的一个枚举。这便是一个Dict ionary (字典)的 

全部。  

Dictionary 的实现过程并不麻烦。下面列出一种简单的方法,它使用了两个Vector,一个用于容纳键,另一 

个用来容纳值:  

  

//: AssocArray。java  

// Simple version of a Dictionary  

import java。util。*;  

  

public class AssocArray extends Dictionary {  

  private Vector keys = new Vector();  

  private Vector values = new Vector();  

  public int size() { return keys。size(); }  

  public boolean isEmpty() {  

    return keys。isEmpty();  

  }  

  public Object put(Object key; Object value) {  

    keys。addElement(key);  

    values。addElement(value);  

    return key;  

  }  

  public Object get(Object key) {  

    int index = keys。indexOf(key);  

    // indexOf() Returns …1 if key not found:  

    if(index == …1) return null;  

    return values。elementAt(index);  

  }  

  public Object remove(Object key) {  



                                                                                          223 


…………………………………………………………Page 225……………………………………………………………

    int index = keys。indexOf(key);  

    if(index == …1) return null;  

    keys。removeElementAt(index);  

    Object returnval = values。elementAt(index);  

    values。removeElementAt(index);  

    return returnval;  

  }  

  public Enumeration keys() {  

    return keys。elements();  

  }  

  public Enumeration e lements() {  

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