java中集合常用类及其详解(四)

2014-11-24 09:44:20 · 作者: · 浏览: 4
代器的快速失败行为应该仅用于检测程序错误。

从Java 2 平台 v1.2起,此类就被改进以实现 Map 接口,使它成为 Java Collections Framework 中的一个成员。不像新的 collection 实现,Hashtable 是同步的

TreeMap:
public class TreeMap
extends AbstractMap
implements NavigableMap, Cloneable, Serializable
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。

此实现为 containsKey、get、put 和 remove 操作提供受保证的 log(n) 时间开销。这些算法是 Cormen、Leiserson 和 Rivest 的 Introduction to Algorithms 中的算法的改编。

注意,如果要正确实现 Map 接口,则有序映射所保持的顺序(无论是否明确提供了比较器)都必须与 equals 一致。(关于与 equals 一致 的精确定义,请参阅 Comparable 或 Comparator)。这是因为 Map 接口是按照 equals 操作定义的,但有序映射使用它的 compareTo(或 compare)方法对所有键进行比较,因此从有序映射的观点来看,此方法认为相等的两个键就是相等的。即使排序与 equals 不一致,有序映射的行为仍然是 定义良好的,只不过没有遵守 Map 接口的常规协定。

注意,此实现不是同步的。如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须 外部同步。(结构上的修改是指添加或删除一个或多个映射关系的操作;仅改变与现有键关联的值不是结构上的修改。)这一般是通过对自然封装该映射的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSortedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的不同步访问,如下所示:

SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));
collection(由此类所有的“collection 视图方法”返回)的 iterator 方法返回的迭代器都是快速失败 的:在迭代器创建之后,如果从结构上对映射进行修改,除非通过迭代器自身的 remove 方法,否则在其他任何时间以任何方式进行修改都将导致迭代器抛出 ConcurrentModificationException。因此,对于并发的修改,迭代器很快就完全失败,而不会冒着在将来不确定的时间发生不确定行为的风险。

注意,迭代器的快速失败行为无法得到保证,一般来说,当存在不同步的并发修改时,不可能作出任何肯定的保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的做法是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测 bug。

此类及其视图中的方法返回的所有 Map.Entry 对都表示生成它们时的映射关系的快照。它们不 支持 Entry.setValue 方法。(不过要注意的是,使用 put 更改相关映射中的映射关系是有可能的。)

此类是 Java Collections Framework 的成员。

sortMap:
public interface SortedMap
extends Map
进一步提供关于键的总体排序 的 Map。该映射是根据其键的自然顺序进行排序的,或者根据通常在创建有序映射时提供的 Comparator 进行排序。对有序映射的 collection 视图(由 entrySet、keySet 和 values 方法返回)进行迭代时,此顺序就会反映出来。要采用此排序方式,还需要提供一些其他操作(此接口是 SortedSet 的对应映射)。

插入有序映射的所有键都必须实现 Comparable 接口(或者被指定的比较器接受)。另外,所有这些键都必须是可互相比较的:对有序映射中的任意两个键 k1 和 k2 执行 k1.compareTo(k2)(或 comparator.compare(k1, k2))都不得抛出 ClassCastException。试图违反此限制将导致违反规则的方法或者构造方法调用抛出 ClassCastException。

注意,如果有序映射要正确实现 Map 接口,则有序映射所维持的顺序(无论是否提供了明确的比较器)都必须与 equals 一致。(有关与 equals 一致 的精确定义,请参阅 Comparable 接口或 Comparator 接口)。这是因为 Map 接口是按照 equals 操作定义的,但有序映射使用它的 compareTo(或 compare)方法对所有键进行比较,因此从有序映射的角度来看,此方法认为相等的两个键就是相等的。即使顺序与 equals 不一致,树映射的行为仍然是 定义良好的,只不过没有遵守 Map 接口的常规协定。

所有通用有序映射实现类都应该提供 4 个“标准”构造方法:1) void(无参数)构造方法,它创建一个空的有序映射,按照键的自然顺序进行排序。2) 带有一个 Comparator 类型参数的构造方法,它创建一个空的有序映射,根据指定的比较器进行排序。3) 带有一个 Map 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系与参数相同,按照键的自然顺序进行排序。4) 带有一个 SortedMap 类型参数的构造方法,它创建一个新的有序映射,其键-值映射关系和排序方法与输入的有序映射相同。无法保证强制实施此建议,因为接口不能包含构造方法。

注:一些方法返回具有受限键范围的子映射。这些范围区间是半开的,也就是说,它们包括低端点,但不包括高端点(如果适用)。如果需要一个闭区间(同时包括两个端点),且键类型允许计算给定键值的后继值,则只需要请求从 lowEndpoint 到 successor(highEndpoint) 的子区间。例如,假设 m 是一个用字符串作为键的映射。下面的语句将得到一个包含 m 中键在 low 和 high(包括)之间的所有键-值映射关系的视图:

SortedMap sub = m.subMap(low, high+"\0");
可使用类似的技术生成一个开区间 (两个端点都不包括)。下面的语句将得到一个包含 m 中键在 low 和 high(不包括)之间的所有键-值映射关系的视图:
SortedMap sub = m.subMap(low+"\0", high);
此接口是 Java Collections Framework 的成员。

Set:
public interface Set
extends Collection
一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。

在所有构造方法以及 add、equals 和 hashCode 方法的协定上,Set 接口还加入了其他规定,这些规定超出了从 Collection 接口所继承的内容。出于方便考虑,它还包括了其他继承方法的声明(这些声明的规范已经专门针对 Set 接口进