未验证 提交 3c00b640 编写于 作者: 飞龙 提交者: GitHub

Update 2.md

上级 8103d394
# 第二章
# 抽象数据类型
# 第二章 抽象数据类型
 本书中包含大多数课程中的经典数据结构,如一些具有代表性的数据集合框架。这意味着其中包括了一些可能使这些值变得有序值的集合或多元集合[1]。其中一些数据集合是关联索引的;它们是搜索结构,拥有类似于将某些索引值(键)映射到其他数据(例如将名称映射到街道地址)的函数。
> 译者:[Allenyep](https://github.com/Allenyep)
 我们可以通过介绍不同数据结构的操作集来描述抽象的情况-即通过描述可用的抽象数据类型。从程序的角度来看,它需要某种数据集合用于操作,而这一系列操作方法必须是大家都应该知道的
本书中包含大多数课程中的经典数据结构,如一些具有代表性的数据集合框架。这意味着其中包括了一些可能使这些值变得有序值的集合或多元集合[1]。其中一些数据集合是关联索引的;它们是搜索结构,拥有类似于将某些索引值(键)映射到其他数据(例如将名称映射到街道地址)的函数
 对于每种不同的抽象数据类型,通常有几种可能的实现方式。选择哪个数据结构取决于你的程序需要处理多少数据,处理数据的速度有多快,以及对存储空间的限制。对于很多程序来说,这有点像一个肮脏的秘密交易,你选择实现的方式完全不重要。然而,知识丰富的程序员应该熟悉这些可用的工具
我们可以通过介绍不同数据结构的操作集来描述抽象的情况-即通过描述可用的抽象数据类型。从程序的角度来看,它需要某种数据集合用于操作,而这一系列操作方法必须是大家都应该知道的
 我希望你们中的许多人会发现这一章令人沮丧,因为它将谈论数据类型的*接口*,而不是谈论它们背后的实现方法。习惯它。毕竟,在这套标准库背后有广泛使用的编程语言将会以一组接口的方式呈现给你。包括:函数中参数传递的方向以及一些注释,通常是使用英语来描述接口的作用。作为一名开发者,您将花费大量时间来生成向您的客户提供相同功能的模块。
对于每种不同的抽象数据类型,通常有几种可能的实现方式。选择哪个数据结构取决于你的程序需要处理多少数据,处理数据的速度有多快,以及对存储空间的限制。对于很多程序来说,这有点像一个肮脏的秘密交易,你选择实现的方式完全不重要。然而,知识丰富的程序员应该熟悉这些可用的工具。
我希望你们中的许多人会发现这一章令人沮丧,因为它将谈论数据类型的*接口*,而不是谈论它们背后的实现方法。习惯它。毕竟,在这套标准库背后有广泛使用的编程语言将会以一组接口的方式呈现给你。包括:函数中参数传递的方向以及一些注释,通常是使用英语来描述接口的作用。作为一名开发者,您将花费大量时间来生成向您的客户提供相同功能的模块。
## 2.1 迭代器
 如果我们要开发一些数据集合的概念,我们必须回答这样一个问题:我们如何从这样的数据集合中获取对应项?你可能已经熟悉了一种集合结构——数组。获取其中元素十分简单。例如,要打印数组的内容,您可以编写
如果我们要开发一些数据集合的概念,我们必须回答这样一个问题:我们如何从这样的数据集合中获取对应项?你可能已经熟悉了一种集合结构——数组。获取其中元素十分简单。例如,要打印数组的内容,您可以编写
``` java
for (int i = 0; i < A.length; i += 1)
......@@ -19,15 +20,15 @@ for (int i = 0; i < A.length; i += 1)
```
数组有n个元素,所以这样的循环很容易。但是其他集合呢?例如罐子里"第一个硬币"是哪一个呢?即使我们任意选择给一个集合中的每个元素一个编号,我们将会发现"选取第n个元素"代价将会十分昂贵(想象一下Scheme当中的lists)。
&emsp;尝试对每个集合强加编号以提取其中元素的问题在于它迫使集合的实现者提供比我们的问题可能需要的更加具体的工具。这是一个经典的工程权衡问题:满足一个约束(如获取第n个元素)可能会有其他代价(逐个迭代的代价十分高)。
尝试对每个集合强加编号以提取其中元素的问题在于它迫使集合的实现者提供比我们的问题可能需要的更加具体的工具。这是一个经典的工程权衡问题:满足一个约束(如获取第n个元素)可能会有其他代价(逐个迭代的代价十分高)。
&emsp;所以问题是在不依赖索引或者可能完全没有依赖顺序的情况下提供集合中的元素。Java提供了两种方法作为接口。接口**java.util.Iterator**提供了一种以某种顺序访问集合中所有项目的方法。**java.util.ListIterator**提供以某种特定顺序访问集合中的元素的方法,但没有为每个元素分配索引\[2\]
所以问题是在不依赖索引或者可能完全没有依赖顺序的情况下提供集合中的元素。Java提供了两种方法作为接口。接口**java.util.Iterator**提供了一种以某种顺序访问集合中所有项目的方法。**java.util.ListIterator**提供以某种特定顺序访问集合中的元素的方法,但没有为每个元素分配索引\[2\]
\[2\]:该库还定义了接口java.util.Enumeration,它本质上是同一想法的旧版本。我们不会在这里谈论这个界面,因为最重要的位置是新的程序首选的是迭代器
### 2.1.1 迭代器接口
&emsp;Java库定义了一个接口:**java.util.Iterator**,如代码2.1所示,表示为“在集合中所有元素排序的东西”的概念,但不保证顺序。这只是一个Java接口,它不具备实现类。在Java库中,代表数据项集合以提供对这些元素进行排序的方法的类的标准方法是定义诸如
Java库定义了一个接口:**java.util.Iterator**,如代码2.1所示,表示为“在集合中所有元素排序的东西”的概念,但不保证顺序。这只是一个Java接口,它不具备实现类。在Java库中,代表数据项集合以提供对这些元素进行排序的方法的类的标准方法是定义诸如
``` java
Iterator<SomeType> iterator () { ... }
......@@ -53,7 +54,7 @@ public interface Iterator <T> {
```
代码2.1 **java.util.Iterator**接口
&emsp;编写这个循环的程序员不需要知道对象i必须经历什么样的迭代以产生所请求的元素。即使代表其集合的C发生重大变化也不需要对循环进行修改。
编写这个循环的程序员不需要知道对象i必须经历什么样的迭代以产生所请求的元素。即使代表其集合的C发生重大变化也不需要对循环进行修改。
这种特殊类型的for循环在Java2中是如此常见和有用,版本1.5中它有自己的“语法糖”,称为增强for循环。你可以编写如下代码
......@@ -534,4 +535,4 @@ etc.. .
但是,这种重新设计会有成本。它不像上面列出的那样简单。比如说,ConstantList中的subList方法。这将清晰地返回一个ConstantList,因为如果不允许更改列表,则不允许您更改其中的视图。然而这意味着类型List需要两个subList方法(带有不同名称),一个继承自ConstantList的方法,另一个返回允许修改产生的List。类似的思路适用于迭代器方法的结果,有两个返回方法,一个返回ConstantIterator类型,另一个返回Iterator类型。此外,这个方案的实现并没有解决List的实现问题,即允许添加元素或者清除所有元素,但是不能删除单个元素。为此仍然需要UnsupportedOperationException或更复杂的异常处理类嵌套。
显然,Java设计者决定保留通过测试发现的一些问题,以简化其库的设计。相比之下,C++中相应标准库的设计者选择区分适用于任何集合的操作和仅适用于“可变”集合的操作。然而他们没有用接口设计他们的库;在C++库中引入新类型的集合(collection)或映射(map)显得十分尴尬。
\ No newline at end of file
显然,Java设计者决定保留通过测试发现的一些问题,以简化其库的设计。相比之下,C++中相应标准库的设计者选择区分适用于任何集合的操作和仅适用于“可变”集合的操作。然而他们没有用接口设计他们的库;在C++库中引入新类型的集合(collection)或映射(map)显得十分尴尬。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册