模拟垃圾回收站

这个问题的本质是若将垃圾丢进单个垃圾筒,事实上是未经分类的。但在以后,某些特殊的信息必须恢复,以便对垃圾正确地归类。在最开始的解决方案中,RTTI扮演了关键的角色(详见第11章)。
这并不是一种普通的设计,因为它增加了一个新的限制。正是这个限制使问题变得非常有趣——它更象我们在工作中碰到的那些非常麻烦的问题。这个额外的限制是:垃圾抵达垃圾回收站时,它们全都是混合在一起的。程序必须为那些垃圾的分类定出一个模型。这正是RTTI发挥作用的地方:我们有大量不知名的垃圾,程序将正确判断出它们所属的类型。

 

//: RecycleA.java
// Recycling with RTTI
package c16.recyclea;
import java.util.*;
import java.io.*;

abstract class Trash {
  private double weight;
  Trash(double wt) { weight = wt; }
  abstract double value();
  double weight() { return weight; }
  // Sums the value of Trash in a bin:
  static void sumValue(Vector bin) {
    Enumeration e = bin.elements();
    double val = 0.0f;
    while(e.hasMoreElements()) {
      // One kind of RTTI:
      // A dynamically-checked cast
      Trash t = (Trash)e.nextElement();
      // Polymorphism in action:
      val += t.weight() * t.value();
      System.out.println(
        "weight of " +
        // Using RTTI to get type
        // information about the class:
        t.getClass().getName() +
        " = " + t.weight());
    }
    System.out.println("Total value = " + val);
  }
}

class Aluminum extends Trash {
  static double val  = 1.67f;
  Aluminum(double wt) { super(wt); }
  double value() { return val; }
  static void value(double newval) {
    val = newval;
  }
}

class Paper extends Trash {
  static double val = 0.10f;
  Paper(double wt) { super(wt); }
  double value() { return val; }
  static void value(double newval) {
    val = newval;
  }
}

class Glass extends Trash {
  static double val = 0.23f;
  Glass(double wt) { super(wt); }
  double value() { return val; }
  static void value(double newval) {
    val = newval;
  }
}

public class RecycleA {
  public static void main(String[] args) {
    Vector bin = new Vector();
    // Fill up the Trash bin:
    for(int i = 0; i < 30; i++)
      switch((int)(Math.random() * 3)) {
        case 0 :
          bin.addElement(new
            Aluminum(Math.random() * 100));
          break;
        case 1 :
          bin.addElement(new
            Paper(Math.random() * 100));
          break;
        case 2 :
          bin.addElement(new
            Glass(Math.random() * 100));
      }
    Vector
      glassBin = new Vector(),
      paperBin = new Vector(),
      alBin = new Vector();
    Enumeration sorter = bin.elements();
    // Sort the Trash:
    while(sorter.hasMoreElements()) {
      Object t = sorter.nextElement();
      // RTTI to show class membership:
      if(t instanceof Aluminum)
        alBin.addElement(t);
      if(t instanceof Paper)
        paperBin.addElement(t);
      if(t instanceof Glass)
        glassBin.addElement(t);
    }
    Trash.sumValue(alBin);
    Trash.sumValue(paperBin);
    Trash.sumValue(glassBin);
    Trash.sumValue(bin);
  }
} ///:~

要注意的第一个地方是package语句:
package c16.recyclea;
这意味着在本书采用的源码目录中,这个文件会被置入从c16(代表第16章的程序)分支出来的recyclea子目录中。第17章的解包工具会负责将其置入正确的子目录。之所以要这样做,是因为本章会多次改写这个特定的例子;它的每个版本都会置入自己的“包”(package)内,避免类名的冲突。
其中创建了几个Vector对象,用于容纳Trash句柄。当然,Vector实际容纳的是Object(对象),所以它们最终能够容纳任何东西。之所以要它们容纳Trash(或者从Trash衍生出来的其他东西),唯一的理由是我们需要谨慎地避免放入除Trash以外的其他任何东西。如果真的把某些“错误”的东西置入Vector,那么不会在编译期得到出错或警告提示——只能通过运行期的一个违例知道自己已经犯了错误。
Trash句柄加入后,它们会丢失自己的特定标识信息,只会成为简单的Object句柄(上溯造型)。然而,由于存在多形性的因素,所以在我们通过Enumeration sorter调用动态绑定方法时,一旦结果Object已经造型回Trash,仍然会发生正确的行为。sumValue()也用一个Enumeration对Vector中的每个对象进行操作。
表面上持,先把Trash的类型上溯造型到一个集合容纳基础类型的句柄,再回过头重新下溯造型,这似乎是一种非常愚蠢的做法。为什么不只是一开始就将垃圾置入适当的容器里呢?(事实上,这正是拨开“回收”一团迷雾的关键)。在这个程序中,我们很容易就可以换成这种做法,但在某些情况下,系统的结构及灵活性都能从下溯造型中得到极大的好处。
该程序已满足了设计的初衷:它能够正常工作!只要这是个一次性的方案,就会显得非常出色。但是,真正有用的程序应该能够在任何时候解决问题。所以必须问自己这样一个问题:“如果情况发生了变化,它还能工作吗?”举个例子来说,厚纸板现在是一种非常有价值的可回收物品,那么如何把它集成到系统中呢(特别是程序很大很复杂的时候)?由于前面在switch语句中的类型检查编码可能散布于整个程序,所以每次加入一种新类型时,都必须找到所有那些编码。若不慎遗漏一个,编译器除了指出存在一个错误之外,不能再提供任何有价值的帮助。
RTTI在这里使用不当的关键是“每种类型都进行了测试”。如果由于类型的子集需要特殊的对待,所以只寻找那个子集,那么情况就会变得好一些。但假如在一个switch语句中查找每一种类型,那么很可能错过一个重点,使最终的代码很难维护。在下一节中,大家会学习如何逐步对这个程序进行改进,使其显得越来越灵活。这是在程序设计中一种非常有意义的例子。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索程序
, vector
, double
, value
, 一个
垃圾
位面垃圾回收站、垃圾回收站、回收站 深度清理垃圾、位面垃圾回收站 乐文、垃圾回收站的利润在哪,以便于您获取更多的相关知识。

时间: 2024-09-19 10:05:52

模拟垃圾回收站的相关文章

是谁在制造网络论坛垃圾?

网络 孑草按语:仅为一家之言,言说一种普遍现象,不针对某个具体的对象,仅供参考. 网络论坛随着网媒的发展,为写手和网络人士提供了一个新的交流发言的平台,也正是因为网络论坛的门槛低,集聚人气更为便捷,比起传统纸媒有不可比拟的容量和优势.但同时,网络论坛也极易成为藏污纳垢之地.因而,网络论坛要健康发展,发挥自我的优势,需要建立一套自己的游戏规则,同时,网民的素质也需要提高.否则,就会成为一个垃圾制造厂和垃圾回收站.因而,对网络论坛中不好的现象加以分析,对网络传媒的发展是必要的. 网络论坛追求的就是人

win7回收站无法打开的方法

  回收站几乎是每台电脑必须的设置了,它的功能就是垃圾回收站,我们把一些不需要的文件和程序删除掉,就会自动保存到回收站中,所以称它为垃圾站一点都没有错.这其实也有个好处,我们只要不清理回收站中的垃圾,那些文件就会一直保存在里面,当我们有什么需要的时候可以恢复文件,这对于文件的保护也是很有用处的.这也随之带来一个弊端,就是里面储存的垃圾过多,就会占据很大的空间,这也是不利的.下面小编就来教大家win7旗舰版电脑的回收站打不开了如何解决? 操作方法如下 1.首先,我们返回到win7旗舰版电脑的桌面位

win7系统回收站右键属性菜单消失的解决方法

  回收站是我们电脑中必不可少的小工具,对于它的使用性能根本不需要小编来介绍,因为大家都知道它是垃圾回收站,可以帮我们保存那些不需要使用的文件,这也有一个问题小编需要提醒大家的,就是垃圾回收站我们要及时清理,如果一旦里面文件太多,就会对我们的系统造成负担了.我们怎么查看回收站里文件的多少呢?我们可以右键点击回收站属性,里面就有文件的大小了,但是最近有用户反映说win7系统中回收站右键打不开了,下面小编教大家Win7回收站右键属性不见了的解决方法. win7系统回收站右键属性菜单消失的解决方法 1

广州全球最大真空垃圾系统为何成摆设

政府投入过亿 落成半年闲置 记者 李刚 将生活垃圾用塑料袋打包随手扔进家门口的回收口,"嗖"的一声,垃圾便跑得无影无踪,一分钟之内通过密闭的管道到达垃圾回收站待处理,整个小区不会留下垃圾的一点蛛丝马迹--这是广州市金沙洲"新社区"号称"全球最大真空垃圾系统"的设想.遗憾的是,该系统落成半年.政府综合投入资金过亿元后,这样的"设想"依然还只是个设想. 垃圾口挂着大锁 记者来到广州廉租房.经济适用房和拆迁安置房聚集度最高的金沙洲新

电脑重要文件被删如何还原?回收站都清空了

如果文件没有备份,却被删除了,垃圾回收站也被清空了,我们该如何还原数据呢? 首先,回想一下这些文件有没有可能存在别的地方,例如:移动硬盘,邮箱里,各种网络空间,或是存储卡等等可存储的地方.如果没有的话,你必须马上关闭正使用的一些软件,特别是要停止使用所有实时编录文件索引的软件如:X1.Google桌面或者Windows系统自带的索引服务,它们都有可能完全清除那些你想恢复的文件. 然后,使用QueTek的File Scavenger 或者 Diskeeper的 Undelete程序,通过它们帮助您

用AJAX开发智能Web应用程序之基础篇

一. 什么是AJAX? 这个名字代表了异步javascript+XMLHTTPRequest,并且意味着你可以在基于浏览器的javascript和服务器之间建立套接字通讯.其实AJAX并不是一种新技术,而是已经成功地用于现代浏览器中的若干成功技术的可能性组合.所有的AJAX应用程序实现了一种"丰富的"UI--这是通过javascript操作HTML文档对象模型并且经由XMLHttpRequest实现的精确定位的数据检索来实现的.典型的示例AJAX应用程序是Google Labs(htt

AJAX开发基础教程篇

ajax|基础教程 一. 什么是AJAX? 这个名字代表了异步JavaScript+XMLHTTPRequest,并且意味着你可以在基于浏览器的JavaScript和服务器之间建立套接字通讯.其实AJAX并不是一种新技术,而是已经成功地用于现代浏览器中的若干成功技术的可能性组合.所有的AJAX应用程序实现了一种"丰富的"UI--这是通过JavaScript操作HTML文档对象模型并且经由XMLHttpRequest实现的精确定位的数据检索来实现的.典型的示例AJAX应用程序是Googl

C# API应用整理文档

C# APIC:\ProgramFiles\MicrosoftVisual Studio .NET\ FrameworkSDK\Samples\ Technologies\ Interop\PlatformInvoke\ WinAPIs\CS目录下有大量的调用API的例子.一.调用格式using System.Runtime.InteropServices; //引用此名称空间,简化后面的代码//使用DllImportAttribute特性来引入api函数,注意声明的是空方法,即方法体为空.[D

C#调用windows api的要点

window     在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希望给未在C#中使用过API的朋友一点帮助.另外如果安装了Visual Studio .net的话,在C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Samples\Technologies\Interop\P