模块化编程的一个重要组成部分就是记录库方法的用法并供其他人参考的文档。我们会统一使用应用程序编程接口(API)的方式列出每个库方法名称、签名和简短的描述。我们用用例来指代调用另一个库中的方法的程序,用实现描述实现了某个API方法的Java代码。
我们用java.lang中Math库常用的静态方法说明API的文档格式。
这些方法实现了各种数学函数——它们通过参数计算得到某种类型的值 (random()除外,它没有对应的数学函数,因为它不接受参数)。它们的参数都是double类型且返回值也都是double类型,因此可以将它们看做double数据类型的扩展——这种扩展的能力正是现代编程语言的特性之一。API中的每一行描述了一个方法, 提供了使用该方法所需要知道的所有信息。Math 库也定义了常数PI(圆周率π )和E(自然对数e),你可以在自己的程序中通过这些变量名引用它们。例如,Math. sin(Math.PI/2)的结果是1.0, Math. log(Math.E)的结果也是1.0 (因为Math.sin())的参数是弧度而Math. log())使用的是自然对数函数)。
public class Math | |
---|---|
static double abs(double a) | a的绝对值 |
static max(double a, double b) | a和b中的较大者 |
static double min(double a, double b) | a和b中的较小者 |
static double sin(double theta) | 正弦函数 |
static double cos(double theta) | 余弦函数 |
static double tan(double theta) | 正切函数 |
static double exp(double a) | 指数函数(e*) |
static double log(double a) | 自然对数函数(loga,即Ina) |
static double random() | [0, 1)之间的随机数 |
成千上万个库的在线文档是Java发布版本的一-部分。 为了更好地描述我们的编程模型,我们只是从中节选了本书所用到的若干方法。例如,BinarySearch 中用到了Java的Arrays库中的sort()方法,我们对它的记录如表1.1.7所示。
public Class Arrays | |
---|---|
static void sort(int[] a) | 将数组按升序排序 |
Arrays库不在java.lang中,因此我们需要用import语句导人后才能使用它,与BinarySearch中一样。
为了介绍Java编程、为了科学计算以及算法的开发、学习和应用,我们也开发了若干库来提供一些实用的功能。这些库大多用于处理输入输出。我们也会使用以下两个库来测试和分析我们的实现。第一个库扩展了Math. random()方法.以根据不同的概率密度兩数得到随机值;第二个库则支持各种统计计算。
public class StdRandom | |
---|---|
static void initialize(long seed) | 初始化 |
static double random() | 0到1之间的实数 |
staticint uniform(int N) | 0到N-1之间的整数 |
static int uniform(int lo, int hi) | lo到hi-l之间的整数 |
static double gaussian() | 正态分布,期望值为0,标准差为1 |
static double gaussi an(double m, double s) | 正态分布,期望值为m,标准差为s |
static int discrete(double[] a) | 返回i的概率为a[i] |
staticvoid shuffleCdouble[] a) | 将数组a随机排序 |
public class StdStats | |
---|---|
static double max(double[] a) | 最大值 |
static double min(double[] a) | 最小值 |
static double mean(double[] a) | 平均值 |
static double var(double[] a) | 采样方差 |
static double stddev(double[] a) | 采样标准差 |
static double median(double[] a) | 中位数 |
StdRandom 的initialize()方法为随机数生成器提供种子,这样我们就可以重复和随机数有关的实验。有些方法的实现非常简单,为什么还要在方法库中实现它们?设计良好的方法库对这个问题的标准回答如下。
1.这些方法所实现的抽象层有助于我们将精力集中在实现和测试本书中的算法,而非生成随机数或是统计计算。每次都自己写完成相同计算的代码,不如直接在用例中调用它们要更简洁易懂。
2.方法库会经过大量测试,覆盖极端和罕见的情况,是我们可以信任的。这样的实现需要大量的代码。例如,我们经常需要使用的各种数据类型的实现,又比如Java的Arays库针对不同数据类型对sort()进行了多次重载。