walterwing  
日历
<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789
统计
  • 随笔 - 12
  • 文章 - 1
  • 评论 - 7
  • 引用 - 0

导航

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
在介绍完Collections框架的各个接口之后,下面我们来看一下各接口都有哪些具体的实现类,以及他们的用途。

实现类按照可以分成如下几类:
  • General-purpose implementations are the most commonly used implementations, designed for everyday use. They are summarized in the table below.
  • Special-purpose implementations are designed for use in special situations and display nonstandard performance characteristics, usage restrictions, or behavior.
  • Concurrent implementations are designed to support high concurrency, typically at the expense of single-threaded performance. These implementations are part of the java.util.concurrent package.
  • Wrapper implementations are used in combination with other types of implementations, often the general-purpose ones, to provide added or restricted functionality.
  • Convenience implementations are mini-implementations, typically made available via static factory methods, that provide convenient, efficient alternatives to general-purpose implementations for special collections (for example, singleton sets).
  • Abstract implementations are skeletal implementations that facilitate the construction of custom implementations — described later in the Custom Collection Implementations section. An advanced topic, it's not particularly difficult, but relatively few people will need to do it.
我们先来总结一下general-purpose的实现类:

General-purpose Implementations
Interfaces Implementations
  Hash table Resizable array Tree Linked list Hash table + Linked list
Set HashSet   TreeSet   LinkedHashSet
List   ArrayList   LinkedList  
Queue       LinkedList  
Map HashMap   TreeMap   LinkedHashMap

注意LinkedList同时实现了List和Queue两种接口。

下表是gegeneral-purpose implementations、special-purpose implementations和concurrent implementations的总结:

 Interfaces  gegeneral-purpose  special-purpose  concurrent       
 Set HashSet
TreeSet
LinkedHashSet
EnumSet
CopyOnWriteArraySet
 
 List ArrayList
LinkedList
CopyOnWriteArrayList  
 Queue LinkedList
PriorityQueue
  LinkedBlockingQueue
ArrayBlockingQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
 Map HashMap
TreeMap
LinkedHashMap
EnumMap
WeakHashMap
IdentityHashMap
ConcurrentHashMap


1. Set实现类

Set有三种general-purpose的实现类,HashSet、TreeSet和LinkedHashSet。其中HashSet速度最快(多数操作都是常数时间),TreeSet(多数操作都是log级时间),但TreeSet有序。LinkedHashSet能提供按照插入顺序排列的遍历,他的速度接近于HashSet,但空间消耗稍大(hash table + linked list)。

HashSet和LinkedHashSet都能在构造函数中指定初始的capacity,和load factor,而TreeSet使不能的。

有一点需要注意的是,HashSet的遍历时间是与它自身的容量大小(而不是储存的元素个数)成正比的(线性关系)。因此,如果你要自己指定初始capacity的话,不要搞得太大,那样不仅浪费空间,而且浪费时间。LinkedHashSet的遍历时间只与元素个数成正比

Set有两种special-purpose的实现类:EnumSet和CopyOnWriteArraySet。

·EnumSet的空间和时间性能都很好,可以作为传统上基于int的“位标志”的替换形式,具有高品质、类型安全的优势。
·CopyOnWriteArraySet适合于遍历操作的数量大大超过可变操作的数量时,以及在不能或不想进行同步遍历,但又需要从并发线程中排除冲突时很有用

具体请参见API doc


2. List实现类

List有两种General-purpose的实现类:ArrayList和LinkedList。一般情况下,使用ArrayList总是最好的选择,因为他占用空间小,速度又快。除非你需要大量频繁的插入删除操作,这时LinkedList可能更加适合。

ArrayList能在构造函数中指定capacity,LinkedList不能。

List有一种special-purpose的implementation - CopyOnWriteArrayList,具体参考API doc


3. Queue实现类

Queue有两种general-purpose的实现类:LinkedList和PriorityQueue。LinkedList提供了一种FIFO队列,而PriorityQueue则是根据元素的自然顺序或是指定的Comparator来排列元素。

在java.util.concurrent包里又一个扩展了Queue的BlockingQueue接口。他有如下一些实现类:

4. Map实现类

Map有三种general-purpose的实现类:HashMap、TreeMap和LinkedHashMap。如果你需要SortedMap的操作,或者需要按序遍历Map,就用TreeMap;如果你不关心遍历的顺序,只关心速度,那就用HashMap;如果你需要接近于HashMap的性能,又想能按元素插入顺序来遍历,就用LinkedHashMap。

其实Map和Set是很相似的,只不过一个是元素集合,一个是“键值对”集合。上面介绍的Set中各实现类的性质也同样适用于Map

需要注意的是,LinkedHashMap提供了一个方法:removeEldestEntry。通过重写这个方法,可以定义自觉的策略-在将新映射关系添加到映射时自动移除旧的映射关系。具体参见API doc

Map有三种Special-purpose的实现类:EnumMap, WeakHashMap,和IdentityHashMap。
Map的Concurrent实现类:ConcurrentHashMap。


下面来介绍一下Wrapper实现类

Wrapper实现类是在提供的Collection实例基础之上添加一些额外的功能,就好像设计模式中的decorator

所有的Wrapper都包含在Collections类中,有static方法来创建。

1. Synchronization Wrappers
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);







需要注意的是,不要以为加上Synchronization Wrappers的包装就可以不管同步操作了,当遍历的时候,我们还是要对Collection对象加上对象



加上对象锁。这是因为遍历操作是由对Collection内部的多个操作的调用组成的。



下面的代码演示了如何在遍历时同步:



Collection<Type> c =
    Collections.synchronizedCollection(myCollection);
synchronized(c) {
    
for (Type e : c)
        foo(e);
}
注意如果我们是在遍历Map,不管我们是用key还是用value什么遍历,都要将锁加在Map上:







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




2. Unmodifiable Wrappers







Unmodifiable Wrappers提供如下两种用途:







2.1. 使Collection不可修改。注意要做到这一点,我们必须在使用Unmodifiable Wrappers后,放弃原来的Collection的引用。



2.2. 运行某客户端对你的数据进行只读操作。这时你可以保留原本的Collection的引用,使得你可以随意操作Collection,而客户只读







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);











3. Checked Interface Wrappers



Collections类中提供的各种Collections.checked... 操作,返回指定 collection 的一个动态类型安全视图。试图插入一个错误类型的元素将

导致立即抛出 ClassCastException。假设在生成动态类型安全视图之前,collection 不包含任何类型不正确的元素,并且所有对该collection

的后续访问都通过该视图进行,则可以保证 该 collection 不包含类型不正确的元素。



具体参见API doc





4. Convenience Implementations



4.1 List View of an Array - Arrays.asList()



Arrays.asList()方法返回数组的一个List视图。任何对返回的list上的操作都将写回到数组上,反之亦然。但要注意的是,返回的list并不支持

add、remove操作。



Q:如何得到一个固定长度的list?

A:List<String> list = Arrays.asList(new String[size]);





4.2 Immutable Multiple-Copy List



参见Collections.nCopies()方法



4.3 Immutable Singleton Set



参见Collections.singleton()方法



4.4 Empty Set, List, and Map Constants



Collections.emptySet(), Collections.emptyList(), Collections.emptyMap()










posted on 2008-07-05 11:03 This is Wing 阅读(557) 评论(0)  编辑  收藏 所属分类: Java基础

只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © This is Wing Powered by: 博客园 模板提供:沪江博客