《数据结构与抽象——Java语言描述》第一章学习笔记

感想:以前学数据结构关注于方法及实现,为了完成作业和手写代码,没有从设计层面考虑过,第一章设计一个bag ADT,借助于Java interface实现ADT的规范说明,然后在实现之前通过Java语句来确认或者修改方法的设计决策及相关文档,且这些代码可以作为后续测试实现。

Points:

  • 对要讨论的类,要在实现它们之前使用类似CRC卡和UML这样的工具仔细说明方法;
  • 设计了ADT草稿后,通过写使用ADT的伪代码,确认你理解了操作及它们的设计;
  • 应该说明遇到特殊情况时方法应该采取的动作;
  • 组织ADT规格说明的一种方式是写一个Java接口;
  • 在定义类之前写一个测试它的程序,看看你是否完全理解并满意类中方法的规格说明。

将包(bag)视为一种集合,定义该集合的操作。

  1. 说明一个包

  描述它的数据,并详细说明对应于包行为的方法。(命名方法,选择它们的参数,确定它们的返回值类型,写出注释充分描述它们对包数据的影响)---> Java头和注释

  1.1 UML描述

  返回包中当前的项数:+getCurrentSize(): Integer

  判断是否为空:+isEmpty(): Boolean

  注:通过getCurrentSize是否为0就可判断是否为空,并不是真的需要操作isEmpty,但是它是所谓的便利方法(convenience method)

  添加给定的对象:+add(newEntry: T): boolean

  删除包中所有项:+clear(): void

  删除一项:+remove(): T

  删除特定项:+remove(anEntry: T): Boolean(或者返回T)

  统计某个对象的次数:+getFrequencyOf(anEntry: T): integer

  包中是否含有某对象:+contains(anEntry: T): boolean

  返回数组:+toArray(): T[](定义一个方法返回保存这些项的数组,通常定义一个新的数组来返回)

  1.2 设计决策(特殊条件)

  类的设计者,必须要做出决定如何处理特殊条件,并将这些决策包含在规格说明中。ADT包的文档应该反映这些决策和前面的细节。

  • 假定无效的情形不能发生: 方法可以声明一种假设(即前置条件),这是客户必须遵守的限制。由客户检查在方法调用前这个前置条件是否满足。
  • 忽略无效情形:给出无效数据时方法可能什么也不做。客户也不知道发生了什么。
  • 猜测客户的意图:同上,可能给客户带来麻烦。
  • 返回一个表示问题的值:for example,若客户试图从空包中remove一项时,remove方法应该返回null。返回的值必须是不在包中的值。
  • 返回一个布尔值,表示操作的成功或失败。
  • 抛出一个异常。

  注1:抛出异常经常是Java方法运行期间处理遇到的特殊事件的理想方法。

  注2:ADT规格说明的草稿写完大部分内容,可以专注这些异常情况做详细说明。

  1.3   一个接口

  在实现类之前写接口,可以让你以简洁的方式记录你的规格说明。然后可将接口中的代码用在具体类的框架中。接口为包提供数据类型,不依赖于具体类的实现,也可以做到,同一种接口不同实现。

BagInterface.java

/**
* An interface that describes the operations of a bag of objects.
* @author Administrator
*
*/
public interface BagInterface <T> {
/**
* Gets the current number of entries in this bag.
* @return: The integer number of entries currently in the bag.
*/
public int getCurrentSize(); /**
* Sees whether this bag is empty.
* @return: True if the bag is empty, or false if not.
*/
public boolean isEmpty(); /**
* Adds a new entry to this bag.
* @param newEntry: The object to be added as a new entry.
* @return: True if the addition is successful, or false if not.
*/
public boolean add(T newEntry); /**
* Removes one unspecified entry from this bag, if possible.
* @return: Either the removed entry, if the removel was successful, or null.
*/
public T remove(); /**
* Removes one occurrence of a given entry from this bag, if possible.
* @param anEntry: The entry to be removed.
* @return: True if the removal was successful, or false if not.
*/
public boolean remove(T anEntry); /**
* Removes all entries from this bag.
*/
public void clear(); /**
* Counts the number of times a given entry appears in this bag.
* @param anEntry: The entry to counted.
* @return: The number of times anEntry appears in the bag.
*/
public int getFrequencyOf(T anEntry); /**
* Tests whether this bag contains a given entry.
* @param anEntry: The entry to locate.
* @return: True if the bag contains anEntry, or false if not.
*/
public boolean contains(T anEntry); /**
* Retrieves all entries that are in this bag.
* @return: A newly allocated array of all the entries in the bag.
* Note: If the bag is empty, the returned array is empty.
*/
public T[] toArray(); } // end BagInterface

  程序设计技巧:在实现一个类之前写测试程序

  写Java语句来测试一个类的方法,将有助于完全理解方法的规格说明。在能正确实现方法之前必须理解它。如果你也是类的设计者,那么使用这个类可能有助于你对设计或对文档进行理想的修改。后面可以使用这些相同的Java语句来测试你的实现。

  2. 使用ADT包

  示例:在线购物(商品放入bag内,顺序不重要)

  在线购物中购物袋的维护程序:

  需要的Item.java

/**
* A class of items for sale.
* @author Administrator
*
*/
public class Item { private String description;
private int price; public Item(String productDescription, int productPrice) {
description = productDescription;
price = productPrice;
} // end constructor public String getDescription() {
return description;
} // end getDescription public int getPrice() {
return price;
} // end getPrice public String toString() {
return description + "\t$" + price / 100 + "." + price % 100;
} // end toString
} // end Item

OnlineShopper.java

/**
* A class that maintains a shopping cart for an online store.
* @author Administrator
*
*/
public class OnlineShopper { public static void main(String[] args) {
Item[] items = {
new Item("Bird feeder", 2050),
new Item("Squirrel guard", 1547),
new Item("Bird bath", 4499),
new Item("Sunflower seeds", 1295)
}; BagInterface<Item> shoppingCart = new Bag<>();
int totalCost = 0; // Statements that add selected items to the shopping cart:
for(int index = 0; index < items.length; index++) {
Item nextItem = items[index]; // Simulate getting item from shopper
shoppingCart.add(newEntry);
totalCost = totalCost + nextItem.getPrice();
} // end for // Simulate checkout
while(!shoppingCart.isEmpty()) {
System.out.println(shoppingCart.remove());
} System.out.println("Total cost: \t$" + totalCost / 100 + "." + totalCost % 100);
} // end main } // end OnlineShopper /*
output:
Sunflower seeds $12.95
Bird bath $44.99
Squirrel guard $15.47
Bird feeder $20.50
Total cost: $93.91 *

  作为设计原则,抽象要求你关注于what而不是how。当你设计一个ADT并最终设计一个类时,使用数据抽象将关注焦点集中在你想对数据做什么,而不必担心如何完成这些任务。

  3. ADT集合

  集合(set)。不允许有重复项。所以包的add和remove方法需要修改,且不需要getFrequencyOf方法,因为总是1或0,可以使用contains方法。

接口SetInterface.java

/**
* An interface that describes the operations of a set of objects.
* @author Administrator
*
*/
public interface SetInterface<T> { public int getCurrentSize();
public boolean isEmpty(); /**
* Adds a new entry to this set, avoiding duplicates(副本).
* @param newRntry: The object to be added as a new entry.
* @return: True if the addtion is successful, or false if the item already is in the set.
*/
public boolean add(T newRntry); /**
* Removes a specific entry from this set, if possible.
* @param anEntry: The entry to be removed
* @return: True if the removal was successful, or false if not.
*/
public boolean remove(T anEntry); public T remove();
public void clear();
public boolean contains(T anEntry);
public T[] toArray();
} // end SetInterface

  4. java类库:接口Set

  java类库是类和接口的集合,这是程序员要学习的。Java集合框架(Java Collections Framework)是这个库的一个子库,它为我们提供了表示及处理集合的统一方式。我们将说明的Java类库中的大多数类和接口都是这个框架的一部分。

标准接口Set,属于java.util。遵循接口规范的集合(set),不包含让x.equals(y)为真的对象对x和y。

Set中方法与SetInterface中对应方法的不同之处:

Public Boolean add(T newEntry)

Public Boolean remove(Object anEntry)

Public void clear()

Public Boolean contains(Object anEntry)

Public Boolean isEmpty()

Public int size()

Public Object[] toArray()

(一)从设计的角度来看ADT(Java)的更多相关文章

  1. 从jvm的角度来看单例模式

    最近在看jvm,发现随着自己对jvm底层的了解,现在对java代码可以说是有了全新的认识.今天就从jvm的角度来看一看以前自以为很了解的单例模式. 了解单例模式的人都知道,单例模式有两种:" ...

  2. Atitit.异常的设计原理与 策略处理 java 最佳实践 p93

    Atitit.异常的设计原理与 策略处理 java 最佳实践 p93 1 异常方面的使用准则,答案是:: 2 1.1 普通项目优先使用异常取代返回值,如果开发类库方面的项目,最好异常机制与返回值都提供 ...

  3. Atitit.ati orm的设计and架构总结 适用于java c# php版

    Atitit.ati orm的设计and架构总结 适用于java c# php版 1. Orm的目标1 1.1. 动态obj1 1.2. Hb的api(meger,save,update,del)1 ...

  4. 在一个千万级的数据库查寻中,如何提高查询效率?分别说出在数据库设计、SQL语句、java等层面的解决方案。

    在一个千万级的数据库查寻中,如何提高查询效率?分别说出在数据库设计.SQL语句.java等层面的解决方案. 解答: 1)数据库设计方面: a. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 whe ...

  5. Atitit  文件上传  架构设计 实现机制 解决方案  实践java php c#.net js javascript  c++ python

    Atitit  文件上传  架构设计 实现机制 解决方案  实践java php c#.net js javascript  c++ python 1. 上传的几点要求2 1.1. 本地预览2 1.2 ...

  6. 计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场

    计算机课程设计-校园二手书交易系统java二手交易平台代码ssm二手商城购物平台跳蚤市场 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM(S ...

  7. 从jvm的角度来看java的多线程

    最近在学习jvm,发现随着对虚拟机底层的了解,对java的多线程也有了全新的认识,原来一个小小的synchronized关键字里别有洞天.决定把自己关于java多线程的所学整理成一篇文章,从最基础的为 ...

  8. 从“思考”的角度来看如何成为一名优质的Java架构师

    导读: 架构师应不应该写代码 为什么别人的系统总是那么烂 成为架构师最困难的门槛是什么? 如何更高效的学习? 1.架构师应不应该写代码 合格的程序员对于明确分配的任务会完成的很好,但是大部分情况下&q ...

  9. 从IDEA角度来看懂UML图

    前言 我们目前已经学习了设计模式的7种设计原则.下面本该是直接进入具体的设计模式系列文章. 但是呢在我们学习设计模式之前我们还是有必要了解一下uml图.因为后续的设计模式文章不出意外应该会很多地方使用 ...

随机推荐

  1. 利用Python 脚本生成 .h5 文件 代码

    利用Python 脚本生成 .h5 文件 import os, json, argparse from threading import Thread from Queue import Queue ...

  2. .net 打包下载

      ZipArchive 打包下载 private IActionResult DownloadZipFromUrl(string[] guids,string zipFullName) { usin ...

  3. swagger实战踩坑1

    1.swagger error 有详细的错误信息 自己根据详细信息找问题 2.swagger error 无详细的错误信息 Controller是否重名=>重名,指定不同的   [Route(& ...

  4. Kibana——日志可视化工具

    Kibana 基础入门 kibana产品介绍 Kibana :是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作.Kibana 提供搜索.查看和与存储在 Elasticsearch ...

  5. Robot Framework+AutoItLibrary+AutoIt使用

    使用记录: 1. 打开被测桌面程序: 2. 打开AutoIt,用finder tool拖拽到控件上,可以看到控件的信息: 3. 如果空间的Title.Control Info抓不到,可以看Mouse下 ...

  6. win10 右键菜单很慢的解决方式

    本来想用 win7 的,不想花很多时间折腾了.现在新电脑主板硬盘CPU都在排挤 win7 ,真是可怜呀.正题: 新电脑的性能应该还算不错的, 18 年跑分 29w 以上,但在图标上面右键却都要转圈几秒 ...

  7. 【译】第18节---数据注解-ForeignKey

    原文:http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-fi ...

  8. JMeter 生成CSV文件中文变乱码的问题

    在通过BeanShell 生成CSV文件时,写入的中文字符默认情况会变成乱码. //默认情况生成的文件是asii编码.fileName = “c:\test.csv";fos = new F ...

  9. php CLI SAPI 内置Web Server

    PHP 5.4.0起, CLI SAPI 提供了一个内置的Web服务器. 这个内置的Web服务器主要用于本地开发使用,不可用于线上产品环境. URI请求会被发送到PHP所在的的工作目录(Working ...

  10. 《剑指offer》第四十一题(数据流中的中位数)

    // 面试题41:数据流中的中位数 // 题目:如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么 // 中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值, // ...