Wrapper Implementations

包装器实现将其所有实际工作委托给指定的集合,但在此集合提供的功能之上添加了额外的功能。对于设计 Pattern 爱好者,这是* decorator *Pattern 的示例。尽管它看起来有些奇特,但确实非常简单。

这些实现是匿名的。该库提供了一个静态工厂方法,而不是提供公共类。所有这些实现都在Collections类中找到,该类仅由静态方法组成。

Synchronization Wrappers

同步包装器将自动同步(线程安全)添加到任意集合。六个核心集合interfaceCollectionSetListMapSortedSetSortedMap均具有一个静态工厂方法。

public static <T> Collection<T> synchronizedCollection(Collection<T> c);
public static <T> Set<T> synchronizedSet(Set<T> s);
public static <T> List<T> synchronizedList(List<T> list);
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m);
public static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s);
public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m);

这些方法中的每一个都返回一个由指定集合备份的同步(线程安全)Collection。为了保证 String 行访问,必须通过返回的 collection 完成对 backing collection 的所有访问。确保这一点的简单方法是不保留对后备集合的引用。使用以下技巧创建同步的集合。

List<Type> list = Collections.synchronizedList(new ArrayList<Type>());

以这种方式创建的集合与正常同步的集合(例如Vector)一样,在线程安全性上都一样。

面对并发访问,当用户在返回的集合上进行迭代时,必须手动对其进行同步。原因是迭代是通过对集合的多次调用来完成的,这些调用必须组成一个原子操作。以下是对包装器同步的集合进行迭代的惯用法。

Collection<Type> c = Collections.synchronizedCollection(myCollection);
synchronized(c) {
    for (Type e : c)
        foo(e);
}

如果使用显式迭代器,则必须从synchronized块内调用iterator方法。不遵循此建议可能导致不确定的行为。遍历已同步MapCollection视图的习惯用法是相似的。如下面的示例所示,当用户遍历其Collection视图中的任何一个时,必须在同步的Map上进行同步,而不是在Collection视图本身上进行同步。

Map<KeyType, ValType> m = Collections.synchronizedMap(new HashMap<KeyType, ValType>());
    ...
Set<KeyType> s = m.keySet();
    ...
// Synchronizing on m, not s!
synchronized(m) {
    while (KeyType k : s)
        foo(k);
}

使用包装器实现的一个小缺点是您没有能力执行包装器实现的任何* noninterface *操作。因此,例如,在前面的List示例中,您不能在已包装的ArrayList上调用ArrayListensureCapacity操作。

Unmodifiable Wrappers

与为包装的集合添加功能的同步包装不同,不可修改的包装会删除功能。特别是,它们通过拦截所有将修改集合并抛出UnsupportedOperationException的操作来取消修改集合的功能。不可修改的包装器有两个主要用途,如下所示:

  • 使集合一旦构建便不可变。在这种情况下,最好不要保留对后备集合的引用。这绝对保证了不变性。

  • 允许某些 Client 端以只读方式访问您的数据结构。您保留对后备集合的引用,但分发对包装器的引用。这样,在您保持完全访问权限的同时,Client 端可以查看但不能修改。

像同步包装器一样,六个核心Collectioninterface中的每个interface都有一个静态工厂方法。

public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c);
public static <T> Set<T> unmodifiableSet(Set<? extends T> s);
public static <T> List<T> unmodifiableList(List<? extends T> list);
public static <K,V> Map<K, V> unmodifiableMap(Map<? extends K, ? extends V> m);
public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<? extends T> s);
public static <K,V> SortedMap<K, V> unmodifiableSortedMap(SortedMap<K, ? extends V> m);

已检查的interface包装器

提供了Collections.checked * interface *包装器,以用于通用集合。这些实现返回指定集合的“动态”类型安全视图,如果 Client 端try添加错误类型的元素,则该视图将抛出ClassCastException。该语言中的泛型机制提供了编译时(静态)类型检查,但是有可能破坏这种机制。动态类型安全视图完全消除了这种可能性。