首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

浅析Java中的会合包(ArrayList,LinkedList,Vector, Stack,HashSet,TreeSet,HashMap,TreeMap)

2013-11-23 
浅析Java中的集合包(ArrayList,LinkedList,Vector, Stack,HashSet,TreeSet,HashMap,TreeMap)??????? 集合

浅析Java中的集合包(ArrayList,LinkedList,Vector, Stack,HashSet,TreeSet,HashMap,TreeMap)

??????? 集合包是Java中最常用的包,它最常用的有Collection和Map两个接口的实现类,Collection用于存放多个单对象,Map用于存放Key-Value形式的键值对。

??????? Collection中常用的又分为两种类型的接口:List和Set,两者最明显的差别为List支持放入重复的对象,而Set不支持。List接口常用的实现类有:ArrayList,LinkedList,Vector和Stack;Set接口常用的实现有HashSet,TreeSet。而Map的常用实现有TreeMap和HashMap。

?

一、ArrayList

1. ArrayList基于数组方式实现,无容量的限制。

2. ArrayList在执行插入元素时可能要扩容,在删除数组时并不会减少数组的容量(如希望相应的减少数组的容量,可以调用ArrayList的trimToSize()),在查找元素时需要遍历数组,对于非null的元素采取equals的方式寻找。

3.ArrayList是非线程安全的。

?

二、LinkedList

1. LinkedList基于双向链表机制实现。

2. LinkedList在插入元素时,必须创建一个新的Entry对象,并切换相应元素的前后元素的引用;在查找元素时,须遍历列表;在删除元素时,要遍历列表,找到要删除的元素,然后从列表上将此元素删除即可。

3. LinkedList是非线程安全的。

?

从LinkedList和ArrayList的区别来看,我们可容易的得出什么时候使用ArrayList,什么时候使用LinkedList:

???? 1)对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。
???? 2)? 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。

?

三、Vector

????? 和ArrayList的不同点有

????? 1) Vector是基于Synchronized实现的线程安全的ArrayList。即Vector是线程安全的。

????? 2)在插入元素时容量扩充的机制和ArrayList稍微有所不同,Vector是扩充2倍,并可通过传入capacityIncrement来控制容量的扩充。而ArrayList是扩充1.5倍并加1。

?

四、Stack

? ? ? Stack继承与Vector,在Vector的基础上实现了Stack所要求的后进先出(LIFO)的弹出即压入操作,其提供了push,pop,peek等三个主要方法。

?

五、HashSet

? ? ? 1. HashSet基于HashMap实现,无容量限制。

? ? ? 2. HashSet是非线程安全的。?

????? 3. HashSet不保证有序。

?

六、TreeSet

????? 1、TreeSet基于TreeMap实现,支持排序。

????? 2、TreeSet是非线程安全的。

?

从对HashSet和TreeSet的描述来看,TreeSet和HashSet一样,也是完全基于Map来实现的,并且都不支持get(int)来获取指定位置的元素(需要遍历获取),另外TreeSet还提供了一些排序方面的支持。例如传入Comparator实现、descendingSet以及descendingIterator等。

?

七、LinkedHashSet:

????? 1. LinkedHashSet 以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代

????? 2. LinkedHashSet同样是非线程安全的。

?

在同步并发环境下,为了确保Set是线程安全的,可以使用Collections.synchronizedSet(new HashSet());因为其能够返回原始hashset集合的同步版本,在多线程环境中可以访问这个同步版本。

?

LinkedHashSet, HashSet,TreeSet三者的区别:

HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放;

LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代; ?

TreeSet:提供一个使用红黑树结构存储Set接口的实现,对象以升序顺序存储,访问和遍历的时间很快。

HashSet
HashSet有以下特点
1) 不能保证元素的排列顺序,顺序有可能发生变化
2) 不是同步的
3) 集合元素可以是null,但只能放入一个null
???? 当向HashSet结合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值来决定该对象在HashSet中存储位置。
???? 简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相等。
???? 注意,如果要把一个对象放入HashSet中,重写该对象对应类的equals方法,也应该重写其hashCode()方法。其规则是如果两个对象通过equals方法比较返回true时,其hashCode也应该相同。另外,对象中用作equals比较标准的属性,都应该用来计算 hashCode的值。

?

LinkedHashSet
???? LinkedHashSet集合同样是根据元素的hashCode值来决定元素的存储位置,但是它同时使用链表维护元素的次序。这样使得元素看起来像是以插入顺序保存的,也就是说,当遍历该集合时候,LinkedHashSet将会以元素的添加顺序访问集合的元素。
???? LinkedHashSet在迭代访问Set中的全部元素时,性能比HashSet好,但是插入时性能稍微逊色于HashSet。

?

TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0。


自然排序
?????? 自然排序使用要排序元素的CompareTo(Object obj)方法来比较元素之间大小关系,然后将元素按照升序排列
??????? Java提供了一个Comparable接口,该接口里定义了一个compareTo(Object obj)方法,该方法返回一个整数值,实现了该接口的对象就可以比较大小。
obj1.compareTo(obj2)方法如果返回0,则说明被比较的两个对象相等,如果返回一个正数,则表明obj1大于obj2,如果是负数,则表明obj1小于obj2。
如果我们将两个对象的equals方法总是返回true,则这两个对象的compareTo方法返回应该返回0


定制排序
?????? 自然排序是根据集合元素的大小,以升序排列,如果要定制排序,应该使用Comparator接口,实现 int compare(T o1,T o2)方法.

?

八、HashMap

?????? 1、HashMap采用数组方式存储key,value构成的Entry对象,无容量限制。

?????? 2、HashMap基于Key hash查找Entry对象存放到数组的位置,对于hash冲突采用链表的方式来解决。

?????? 3、HashMap在插入元素时可能会要扩大数组的容量,在扩大容量时须要重新计算hash,并复制对象到新的数组中。

?????? 4、HashMap是非线程安全的。

?????? 5、HashMap遍历使用的是Iterator

?

九、HashTable

????? 1、HashTable是线程安全的。

????? 2、HashTable中无论是Key,还是Value都不允许为null。

????? 3.?? HashTable遍历使用的是Enumeration。

?

曾经HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable,可以使用ConcurrentHashMap。那么几者之间有什么区别呢?

????? 1、HashTable的内部存储结构

HashTable和HashMap采用相同的存储机制,二者的实现基本一致,不同的是:

???? 1)、HashMap是非线程安全的,HashTable是线程安全的,内部的方法基本都是synchronized。

???? 2)、HashTable不允许有null值的存在。

在HashTable中调用put方法时,如果key为null,直接抛出NullPointerException。其它细微的差别还有,比如初始化Entry数组的大小等等,但基本思想和HashMap一样。

?????? 2、HashTable和ConcurrentHashMap的比较

ConcurrentHashMap是目前最好的线程安全的HashMap的实现。同样是线程安全的类,它与HashTable在同步方面有什么不同呢?

HashTable使用synchronized关键字来确保同步,而Synchronized其实是对对象加锁,不论你是在方法前加synchronized还是语句块前加,锁住的都是对象整体, 但是ConcurrentHashMap的同步机制和这个不同,它不是加synchronized关键字,而是基于lock操作的,这样的目的是保证同步的时候,锁住的不是整个对象。事实上,ConcurrentHashMap可以满足concurrentLevel个线程并发无阻塞的操作集合对象。

?

需要特别注意的是,我们在具体的项目开发中必须对HashMap的非线程安全保持足够的关注,如果在并发场景中不保持足够的同步,就有可能在执行HashMap.get是进入死循环,将CPU耗到100%。

?

十、TreeMap:

?????? 1、SortMap的实现

?????? 2、TreeMap是一个典型的基于红黑树的Map实现,因此它要求一定要有Key比较的方法,要么传入Comparator实现,要么key对象实现Comparable接口。

?????? 3、TreeMap是非线程安全的。

??????

?

十一、LinkedHashMap:

???? 1. LinkedHashMap 是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.

???? 2. LinkedHashMap 也可以在构造时用带参数,按照应用次数排序。

?

LinkedHashMap在遍历的时候会比HashMap慢。不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比 LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

?

热点排行