《数据结构与抽象——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. [午间休息] - 午间codewars活跃脑袋

    https://www.codewars.com/kata/51f2b4448cadf20ed0000386/javascript 中午是一个易困的时间段.如果其它人不睡觉还好. 这个js题目就是说如 ...

  2. Oracle 基础学习笔记

    知识点 一.登陆数据库: 登陆数据库: sqlplus system/oracle123456 二.新建用户.授权(连接数据库.创建表.表空间.查询某用户下的表) 语法: create user [用 ...

  3. kubernets实战采坑1

    1.NLog.config失效,日志ElasticSearch的Index不匹配 <?xml version="1.0" encoding="utf-8" ...

  4. 解决Linux服务器磁盘空间不足的问题

    在linux服务器执行程序时报错: awk: write failure (No space left on device)awk: close failed on file /dev/stdout ...

  5. vue.js精讲01

    笔记及源码地址 : https://github.com/wll8/vue_note 01 2017-09-13 view一个 mvvm框架(库),和 ag 类似.比较小巧,容易上手. mvc: mv ...

  6. js仿ppt,在线演示文档:Impress.js

    (附件) Impress.js是一款基于css3转 换和过渡.工作于现代浏览器(Google Chrome或Safari (或 Firefox 10 或 IE10)).并受prezi.com的理念启发 ...

  7. 细菌多位点序列分型(Multilocus sequence typing,MLST)的原理及分型方法

    摘 要: 多位点序列分型(MLST)是一种基于核酸序列测定的细菌分型方法,通过PCR扩增多个管家基因内部片段,测定其序列,分析菌株的变异,从而进行分型.MLST被广泛应用于病原菌.环境菌和真核生物中. ...

  8. _spellmod_aura_trigger

    一.spell.dbc做一个空光环 二.配置_spellmod_aura_trigger表 comment 备注 aura 光环ID,有此光环时,才会触发下面技能 linkSpell1-3 链接的技能 ...

  9. mime模块响应或设置Node.js的Content-Type头

    转载自:https://itbilu.com/nodejs/core/VJYaAfKrl.html   MIME,即:Multipurpose Internet Mail Extensions,多用途 ...

  10. CentOS 7 安装pip2

    使用yum安装python-pip,但是报错,说没有可用的包 安装epel源 [root@sishen yum.repos.d]# yum install -y epel-release 然后再安装 ...