Java Collection Framework

JAVA的集合框架(Java Collection Framework)是JAVA的基础知识,在我们的开发过程中几乎是时时刻刻都要用到的东西。但是因为其中的接口和类很多,我们未必会对其完全熟悉。这里,我就做个简单的归纳和介绍。

  先来看一张图:

 Java Collection Framework - 田胜龙 - 梦中客

 

  从上我们可以看出,最顶端其实就是4个接口:Collection ,List ,Set ,和Map 。 其中List和Set是继承自Collection,而Map则自成一脉。这些接口都是在java.util路径下的,都属于java的基础类库rt.jar。

  这里我们需要说明一下的是,java.util.Collections,是不属于java的集合框架的。它是一个集合的工具类。比如我们常用它的排序方法:Collections.sort(List), Collections.sort(List, Comparator)。

  回到正题。上图中那么多的接口和类,各自的特性是什么呢?这是我们这篇文章关注的重点。我们可以知道,在这个图中,越是下面的子类,特性也就越丰富。而顶层的接口和类,也就越简单。我们在刚接触java的时候,用的最多的可能就是ArrayList和HashMap。我们常用的写法会是这样:

 

Java代码
  1. List<T> pList = new ArrayList<T>();   
  2. Map<K, V> pMap = new HashMap<K, V>();   

List和Map最简单的区别就是:Map存放的是键值对,方便查找。

 

下面我们来看一张比较简单的表格,以区分各个类的差别:

 

 

是否有序

是否允许重复

是否线程同步

Collection

 

List

ArrayList

Vector

LinkedList

Set

HashSet

TreeSet

Map

HashMap

<key, value>,

key不允许重复

TreeMap

Hashtable

 

    可以知道,List是有序集合,而Set和Map则不一定。以Tree开头的都是有序的。而以Hash开头的,是用hash实现的,性能上比用二叉树实现的Tree**要好。

  关于同步问题,一般而言,非同步的类,性能比同步的要好。我们建议用Collections.synchronizedCollection(Collection<T> c)方法去处理原本非同步的类,在不丢失性能的前提下,实现同步。Java1.5提供了ConcurrentHashMap,适用于高并发的线程安全实现。

  

Collection接口 由  Set接口 和 List接口 继承。

      Set 被 Vector . ArrayList LinkedList 实现。

      List 被 HashSet  TreeSet 实现。

Map接口 由 HashTable HashMap  TreeMap 实现。


下面看下每个实现类的特征;;;--》(转的。)

1. List  (有重复、有序)

 Vector基于Array的List,性能也就不可能超越Array,并且Vector是“sychronized”的,这个也是Vector和ArrayList的唯一的区别。

ArrayList:同Vector一样是一个基于Array的,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快。

数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半

LinkedList:LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了所以它适合于进行频繁进行插入和删除操作。这就是LinkedList的优势。Iterator只能对容器进行向前遍历,而 ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。
用在FIFO,用addList()加入元素 removeFirst()删除元素
用在FILO,用addFirst()/removeLast()
ListIterator 提供双向遍历next() previous(),可删除、替换、增加元素

List总结: 1. 所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]; 2. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]; 3. 所有的List中可以有null元素,例如[ tom,null,1 ]; 4. 基于Array的List(Vector,ArrayList)适合查询,而LinkedList(链表)适合添加,删除操作。


2. Set

HashSet:虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是在HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项,这也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。HashSet能快速定位一个元素,但是放到HashSet中的对象需要实现hashCode()方法0。

TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具有相同的排序算法,那就不需要重复定义相同的排序算法,只要实现Comparator接口即可。TreeSet是SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。
      Set总结: 1. Set实现的基础是Map(HashMap); 2. Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象; Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别? Set里的元素是不能重复的,即不能包含两个元素e1、e2(e1.equals(e2))。那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。==方法决定引用值(句柄)是否指向同一对象。


3. Map

 Map是一种把键对象和值对象进行关联的容器,Map有两种比较常用的实现: HashTable、HashMap和TreeMap。

 HashMap也用到了哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它有一些扩展的方法,比如firstKey(),lastKey()等。
只有HashMap可以让你将空值作为一个表的条目的key或value

HashMap和Hashtable的区别。 HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口。主要区别在于HashMap允许空(null)键(key)或值(value),非同步,由于非线程安全,效率上可能高于Hashtable。 Hashtable不允许空(null)键(key)或值(value),Hashtable的方法是Synchronize的,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。

HashMap:
    散列表的通用映射表,无序,可在初始化时设定其大小,自动增长。 
    只有HashMap可以让你将空值作为一个表的条目的key或value

LinkedHashMap:
    扩展HashMap,对返回集合迭代时,维护插入顺序

WeakHashMap:
    基于弱引用散列表的映射表,如果不保持映射表外的关键字的引用,则内存回收程序会回收它

TreeMap:
    基于平衡树的映射表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值