Java的集合类主要由两个接口派生而出: Collection 和 Map, Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
下面的两幅图说明了java中的集合框架:
由上图可以看出,java中的集合类主要可分为四种类型:Set,Queue,List 和 Map。
Set 集合类似于一个罐子,程序可以依次把多个对象“丢进” Set 集合,而Set集合通常不能记住元素的添加顺序,并且不允许包含相同的元素。
Set集合有几个典型实现:
1.HashSet 按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。当向HashSet集合中存入一个元素时,HashSet 会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。此外,HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等。
HashSet还有一个子类 LinkedHashSet,LinkedHashSet集合也是根据元素的hashCode值来决定元
素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也
就是说,当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
2.TreeSet 是SortedSet接口的实现类,正如SortedSet名字所暗示的,TreeSet可以确保集合元素处于排序状态。TreeSet并不是根据元素的插入顺序进行排序的,而是根据元素实际值的大小来进行排序的,其排序功能底层是用红黑树实现的。TreeSet支持两种排序方法:自然排序和定制排序(详情可参看《疯狂java讲义》)。对于TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj)方法比较是否返回0一一如果通过compareTo(Object obj )方法比较返回0, TreeSet 则会认为它们相等;否则就认为它们不相等。
HashSet和TreeSet是Set的两个典型实现,到底如何选择HashSet和TreeSet呢?HashSet的性能总是比TreeSet好(特别是最常用的添加、查询元素等操作〉, 因为TreeSet 需要额外的红黑树算法来维护集合元素的次序。只有当需要一个保持排序的Set 时,才应该使用TreeSet, 否则都应该使用HashSet 。
List 集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,例如第一次添加的元素索引为0 , 第二次添加的元素索引为1 ……
ArrayList 和Vector 都是List 类的两个典型实现(具体区别参看《疯狂java讲义》)。
Queue 用于模拟队列这种数据结构, 队列通常是指“ 先进先出”( FIFO )的容器。队列的头部保存在队列中存放时间最长的元素,队列的尾部保存在队列中存放时间最短的元素。Queue 接口有一个PriorityQueue实现类。除此之外, Queue还有一个Deque接口, Deque代表一个“双端队列”,双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可当成队列使用,也可当成栈使用。Java为Deque提供了 ArrayDeque 和 LinkedList 两个实现类。(如果程序中需要使用栈或者队列这种数据结构,可以使用ArrayDeque和LinkedList这两个类,具体的方法可以查看API)。
Map 用于保存具有映射关系的数据, 因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value, key和value都可以是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false。key和value之间存在单向一对一关系,即通过指定的key,总能找到唯一的、确定的value。从Map中取出数据时,只要给出指定的key,就可以取出对应的value。如果把Map的两组值拆开来看,Map里的数据有如下图所示的结构:
Set和Map关系十分密切,从Java 源码来看,Java是先实现了Map,然后通过包装一个所有value都为null的Map就实现了Set集合。
Map中也有几个典型的实现类:HashMap,Hashtable,LinkedHashMap,TreeMap,WeakHashMap,ldentityHashMap以及EnumMap。其区别类似Set中各实现类的区别,具体区分也可参看《疯狂java讲义》,但一般编程时,还是主要使用 HashMap 和 TreeMap ,对于一般的应用场景,程序应该多考虑使用HashMap,因为HashMap正是为快速查询设计的( HashMap底层其实也是采用数组来存储key-value对)。但如果程序需要一个总是排好序的Map时,则可以考虑使用TreeMap。
Java提供了一个操作Set 、List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序、查询和修改等操作,还提供了将集合对象设置为不可变、对集合对象实现同步控制等方法,写程序时也可能用到。