Java集合浅析

来源:互联网 发布:网络男歌手到不了 编辑:程序博客网 时间:2024/05/21 22:41

一、集合基本概念

Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java JDK不能提供直接继承自Collection的类,Java JDK提供的类都是继承自Collection的"子接口",如:List和Set。(注意:Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当做一组key集合,一组value集合,或者一组key-value映射。)

List:元素有放入顺序,元素可重复 ,其接口有三个实现类:LinkedList,ArrayList,Vector (Vector 还有一个Stack子类,只是比Vector多了5个方法)
Map:元素按键值对存储,无放入顺序 ,key不可重复,其接口有三个实现类:HashMap,HashTable,LinkeHashMap 
Set:元素无放入顺序,元素不可重复,其接口有两个实现类:HashSet,TreeSet 


二、Set 和 Map的关系

Set代表一种集合元素无序、不可重复的集合,Map代表一种由多个key_value对组成的集合,如果将Map集合的所有key集中起来,那这些key就组成一个set集合,set集合可扩展成一个Map集合,只需变为key_value对。(注意:当试图把某个类的对象当成HashMap的key,或者试图将这个类的对象放入HashSet中保存时,重写该类的equels()方法和hashCode()方法很重要

1.HashMap 和 HashSet:

对于HashSet,系统采用Hash算法决定集合元素的存储位置,它是基于HashMap实现的;HashMap把value当成key的附属,而value总是紧随key存储,即HashMap在底层将key-value对当成一个整体进行处理。


2.TreeMap 和 TreeSet:

TreeSet底层采用一个NavigableMap来保存集合的元素,但NavigableMap只是一个接口,因此底层依然是使用TreeMap来包含Set集合中的所有元素;对于TreeMap,采用“红黑树”的排序二叉树来保存Map中每个Entry,每个Entry都被当成“红黑树”的一个节点对待。

优劣:TreeMap和TreeSet添加元素和取出元素都不叫耗性能,优势是TreeMap的Entry总是按key根据指定排序规则保持有序状态,TreeSet中所有元素总是根据指定排序规则保持有序状态。

红黑树:一种自平衡的二叉查找树,树种每个节点的值,都大于或等于在它的左子树中所有节点的值,并且小于或等于在它右子树中所有节点的值,这确保红黑树运行时可以快速的在树种查找和定位所需节点。


三、Map和List的关系

List集合包含两组值,其中一组是虚拟的int类型的引索,另一组是List集合元素,可以说List相当于所有可以都是int类型的Map。


四、ArrayList和LinkedList和Vector

1.Vector和ArrayList的区别:

他们都实现了List接口,底层都是基于Java数组来存储集合元素,ArrayList的实现比Vector更安全,Vector就是ArrayList的线程安全版本,Vector的方法增加了synchronized,是线程安全的,现在Vector基本上被ArrayList所代替了。


2.ArrayList和LinkedList差异、性能:

ArrayList是一种顺序存储的线性表,LinkedList则是一种链式存储的线性表,本质是一个双向链表,ArrayList的性能总体上优于LinkedList,因此绝大部分都应该考虑适用ArrayList集合,但如果程序经常需要添加、删除元素,尤其是经常需要调用add(E e)方法向集合中添加元素是,则应该考虑使用LinkedList集合。


3.四种List介绍:摘自http://blog.csdn.net/abbuggy/article/details/7720666

  • LinkedList类
  LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
  注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));
  • ArrayList类
  ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
  每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
  和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
  • Vector类
  Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
  • Stack 类
  Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
Set接口
  Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
  很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
  请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。


0 0
原创粉丝点击