码迷,mamicode.com
首页 > 其他好文 > 详细

集合框架之集合类概述

时间:2015-01-25 08:44:08      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:集合类   collection   list   map   set   


集合是一组复合元素的容器,用来存储,检索,控制聚合数据并提供它们之间的通信方法

java的集合框架提供了表示和操控集合的统一架构。所有的集合框架都包含下面三个方面:

接口:即集合的抽象数据结构。接口允许我们独立地操纵集合而不用考虑集合的具体实现

实现:即接口的具体实现类。从本质上来讲,它们是可重用的数据结构

算法:即在实现了集合接口的对象上执行有用的计算,比如排序和搜索,的方法。算法是多态的:同名的方法可以被任何合适的接口实现类调用,从本质上来讲,算法是可重用的功能

 

核心集合接口封装了不同类型的集合,它们是java集合框架的基础,形成了下图所示的层级结构

技术分享

从上图中可以看到,Set是一种特殊的Collection,而SortedSet是一种特殊的Set……诸如此类。

需要注意,上图中有两个不同的树,Map并不是Collection的子接口,而是一个独立的接口

所有的集合接口都是泛化的。比如下面是Collection接口的声明:

public interfaceCollection<E>...

“<E>”表示该接口是通用的。当我们声明一个Collection接口时,最好指定该接口包含的对象类型,以便让编译器在编译时检验输入的对象是否正确,从而减少运行时抛出的错误。

对于接口中的方法,有很多是可选择实现的,就是说,它的实现类可以实现该方法,也可以不实现,根据具体需要来决定

 

先,我们来看一下核心的集合接口,对它们有一个整体的感性认识:

Collection接口:集合框架的根接口。它是集合类框架中最具一般性的顶层接口。Java平台没有提供任何该接口的直接具体实现类,但是提供了具有各种不同特性的子接口

Set接口:不允许包含重复值的集合

List接口:可索引的集合,可以包含重复值。使用该接口时我们通过索引对元素进行精准的插入和查找

Queue接口:该集合适用于组织一个队列,队列中的元素按照优先级进行处理。除了继承自Collection接口的方法,该接口还提供了另外的插入、提取和检验方法。典型的队列是符合“先进先出”(FIFO:First In,First Out)原则的,优先级队列是一种例外,它按照元素的优先级顺序排列元素。无论按照什么原则排序,队头元素总是首先被检出。每个Queue接口的实现类必须指定它的排序原则

Deque接口:与Queue的不同之处在于它是一个双端队列,在两端都能插入和移除元素,它继承并扩展了Queue接口

Map接口:提供了键值对(key/value)的映射关系的集合。关键字不能有重复值,每个关键字至多可映射一个值

SortedSet接口:以升序的原则维持着集合中的元素顺序。

SortedMap接口:以关键字升序的原则维持着集合中的元素顺序

 

以上接口的通用实现类(这里的通用实现类一般是指适用于单线程环境下的实现类,在JDK中有针对多线程并发环境下的特殊实现类)总结如下

接口

哈希表实现

可变数组实现

树实现

链表实现

哈希表+链表实现

堆实现

Set

HashSet

 

TreeSet

 

LinkedHashSet

 

List

 

ArrayList

 

LinkedList

 

 

Queue

 

 

 

LinkedList

 

PriorityQueue

Deque

 

 

 

LinkedList

 

 

Map

HashMap

 

TreeMap

 

LinkedHashMap

 

可以发现,LinkedList同时实现了List、Queue、Deque三个接口。

SortedSet接口和SortedMap接口没有在上表中列出,在上面的层次结构图中可以看到,它们分别是Set和Map的子接口,TreeSet和TreeMap就是它们的实现类

以上提到的所有通用实现类都支持为null的元素(或者键/值),不过有的只能包含一个null,有的可以包含多个null;所有通用实现类都实现了Serializable,是可序列化的对象;所有通用实现类都提供了一个clone方法用于复制对象;所有通用实现类都是线程不安全的(即是不同步的);所有通用实现类都提供了”fail-fast”机制的迭代器

关于“fail-fast”机制,来看一个实例:

     

     Map<String,String> map = new HashMap<String,String>();
             map.put("first", "Jay");
             map.put("second","Jack");
             map.put("third", "Jim");
            
             Iterator<String> it= map.keySet().iterator();
             while(it.hasNext()){
                    System.out.println(map.get(it.next()));
                    if(map.containsKey("second")){
                           map.remove("second");
                    }
             }
 

以上代码试图使用Iterator迭代Map里的键值,如果键值为“second”则删除Map中的该元素。运行一下可以发现,执行删除操作时会报java.util.ConcurrentModificationException异常,即便这是单线程。

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

但是,如果上面的代码进行的不是删除操作,而是覆盖掉原来的元素:

if(map.containsKey("second")){
      map.put ("second","Joe");
}

就不会报错,上面的程序中的Iterator是对Map的Key进行迭代,虽然对Map进行了修改,但是只改变了一个元素的value,整个Map的KeySet并没发生变化

如果想要成功的执行删除操作,就需要先对Iterator进行对应的删除操作

Map<String,String> map = new HashMap<String,String>();
             map.put("first","Jay");
             map.put("second","Jack");
             map.put("third","Jim");
            
             Iterator<String> it= map.keySet().iterator();
             while(it.hasNext()){
                    System.out.println(map.get(it.next()));
                    if(map.containsKey("second")){
                           it.remove();  //先对Iterator进行删除
                           map.remove("second");
                    }
             }

除了上面提到的实现类之外,还有两种不常用的实现类:VectorHashtable它们是线程安全的。这是低版本JDK的遗留产物,对于集合而言,大多数情况都没必要支持线程安全。在需要考虑多线程操作的环境下,JDK也提供了多种方法来将上面的通用实现类转换成线程安全的类

如果多个线程同时访问一个实现类,而其中至少一个线程修改了该类,那么它必须保持外部同步。这通常是通过对自然封装该 set 的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用Collections.synchronizedMap方法来“包装”map。最好在创建时完成这一操作,以防止对该 set 进行意外的不同步访问:

   

Map map = Collections.synchronizedMap(newHashSMap(...));



集合框架之集合类概述

标签:集合类   collection   list   map   set   

原文地址:http://blog.csdn.net/u012152619/article/details/42673689

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!