您的位置:首页 > 其它

类级框架——list,map和set(整理)

2011-11-17 20:51 204 查看
概要:list,map和set的概念,以及实现类的对比。
基本概念:

List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。Iterator只能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。


Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有两种比较常用的实现:HashMap和TreeMap。HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object
key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。


Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用类:Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用的方法,Arrays则是对一个数组进行类似的操作。



实现类的对比:




Map接口:

|

+ -- WeakHashMap: 以弱键
实现的基于哈希表的 Map。在 WeakHashMap 中,当某个键不再正常使用时

| ,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对

| 该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射

| 中有效地移除,因此,该类的行为与其他的
Map 实现有所不同。此实现不是同步的。

|

+ -- TreeMap:该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的
Comparator 进行排序,

| 具体取决于使用的构造方法。此实现不是同步的。

|

+ -- HashMap:基于哈希表的
Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和

| null键。(除了非同步和允许使用
null 之外,HashMap 类与 Hashtable 大致相同。)此类

| 不保证映射的顺序,特别是它不保证该顺序恒久不变。此实现不是同步的。

|

+-- SortedMap: 进一步提供关于键的总体排序
的 Map。该映射是根据其键的自然顺序进行排序的,或者根据

通常在创建有序映射时提供的
Comparator 进行排序。对有序映射的 collection 视图(由

entrySet、keySet
和 values 方法返回)进行迭代时,此顺序就会反映出来。要采用此排序方式,

还需要提供一些其他操作(此接口是
SortedSet 的对应映射)。

Collection接口:

|

+ --Set接口:一个不包含重复元素的 collection。更正式地说,set 不包含满足 e1.equals(e2) 的元素对

| | e1
和 e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 set 抽象。

| |

| + -- HashSet:此类实现
Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代

| | 顺序;特别是它不保证该顺序恒久不变。此类允许使用
null 元素。此类为基本操作提供了稳定

| | 性能,此实现不是同步的。

| |

| + -- LinkedHashSet:具有可预知迭代顺序的
Set 接口的哈希表和链接列表实现。此实现与 HashSet 的不同

| | 之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即

| | 按照将元素插入到
set中 的顺序(插入顺序)进行迭代。注意,插入顺序不 受在 set 中重新插入

| | 的元素的影响。此实现不是同步的。

| |

| + -- TreeSet:基于
TreeMap 的 NavigableSet 实现。使用元素的自然顺序对元素进行排序,或者根据创建

| set时提供的
Comparator 进行排序,具体取决于使用的构造方法。此实现为基本操作

| (add、remove和contains)提供受保证的
log(n) 时间开销。此实现不是同步的。

|

+ --List接口:有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确

| 地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

|

+ -- ArrayList:List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括
null 在内的所有

| 元素。除了实现
List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。

| (此类大致上等同于Vector
类,除了此类是不同步的。)每个 ArrayList 实例都有一个容量。

| 该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着向
ArrayList

| 中不断添加元素,其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来

|
分摊固定时间开销那样简单。此实现不是同步的。

|

+ -- LinkedList:List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括
null)。

| 除了实现
List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供

| 了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。提供先进先出队列操作

| (FIFO)。此实现不是同步的。

|

+ -- Vector:Vector
类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的

组件。但是,Vector
的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或 移除项

的操作。此实现是同步的。



各种区别:

TreeSet和HashSet区别:

public class TreeSet<E>

extends AbstractSet<E>

implements SortedSet<E>, Cloneable, java.io.Serializable

public class HashSet<E>

extends AbstractSet<E>

implements Set<E>, Cloneable, java.io.Serializable

其中SortedSet中组合了一个:Comparator<? super E> comparator();

因此 TreeSet与HashSet最大区别在于排序。

Hashtable和HashMap的区别

1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;

2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:

Map Collections.synchronizedMap(Map m)

这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。

3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。

4.其底层的实现机制不同,hashmap的访问速度要快于hashtable,因为它不需要进行同步检验,建议在非多线程环境中使用hashmap代替hashtable .

小结:
HashSet的内部是一个HashMap,TreeSet的内部是一个TreeMap。
TreeMap的原理是红黑树。详细请看《红黑树(Red
Black Tree)- 对于 JDK TreeMap的实现》。
hashMap是数组的hash离散化。hash原理及冲突请看《HashMap原理及冲突之简谈》。

参考资料:

http://www.iteye.com/topic/70587[体力活]Collection接口的总结

http://hi.baidu.com/lovernet/blog/item/d0ef1ad60cd89bd6a044dfbb.html《LinkedHashMap
和 HashMap的区别》

http://space.itpub.net/14734416/viewspace-448840《HashMap原理及冲突之简谈》

/article/9059295.html《红黑树(Red
Black Tree)- 对于 JDK TreeMap的实现》

/article/3983127.html集合类(一):Collection接口

http://gwshuai.iteye.com/blog/99373《Collection
List Set Map 区别记忆》

thomescai http://blog.csdn.net/thomescai(转载请保留)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐