java集合类详解

时间:2022-07-11 17:01:20

Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组、链表、栈、队列、集合、哈希表等。学习Java集合框架下大致可以分为如下五个部分:List列表、Set集合、Map映射、迭代器(Iterator、Enumeration)、工具类(Arrays、Collections)。

Java集合类的整体框架如下:

java集合类详解

从上图中可以看出,集合类主要分为两大类:Collection和Map。

Collection是List、Set等集合高度抽象出来的接口,它包含了这些集合的基本操作,它主要又分为两大部分:List和Set。

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(链表)适合添加,删除操作。

List接口通常表示一个列表(数组、队列、链表、栈等),其中的元素可以重复,常用实现类为ArrayList和LinkedList两者的区别是ArrayList基于数组的形式存储,查找快,增删慢,相反LinkedList基于链表,增删快,查找慢。另外还有不常用的古老集合Vector,线程同步但是效率要低,另外当容量满时会扩容一倍,而ArrayList只是增加50%

ArrayList:同Vector一样是一个基于Array上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。

LinkedList:LinkedList不同于前面两种List,它不是基于Array的,所以不受Array性能的限制。它每一个节点(Node)都包含两方面的内容:1.节点本身的数据(data);2.下一个节点的信息(nextNode)。所以当对LinkedList做添加,删除动作的时候就不用像基于Array的List一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这就是LinkedList的优势。

Vector : 基于Array的List,其实就是封装了Array所不具备的一些功能方便我们使用,它不可能走出Array的限制。性能也就不可能超越Array。所以,在可能的情况下,我们要多运用Array。另外很重要的一点就是Vector“synchronized”的,这个也是Vector和ArrayList的唯一的区别。

Stack: 这个类从Vector派生而来,并且增加了方法实现栈??一种后进先出的存储结构。可以用来装activity,要知道activity就是以堆栈的形式管理的。


Set总结:

编辑
1. Set实现的基础是Map(HashMap);2. Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象

Set接口通常表示一个集合,其中的元素不允许重复(通过hashcode和equals函数保证),常用实现类有HashSet,LinkHashSet和TreeSet,HashSet是通过Map中的HashMap实现的,而TreeSet是通过Map中的TreeMap实现的。另外,TreeSet还实现了SortedSet接口,因此是有序的集合(集合中的元素要实现Comparable接口,并覆写Compartor函数才行)。
HashSet:虽然Set同List都实现了Collection接口,但是他们的实现方式却大不一样。List基本上都是以Array为基础。但是Set则是 在HashMap的基础上来实现的,这个就是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。看看 HashSet的add(Object obj)方法的实现就可以一目了然了。public boolean add(Object obj){return map.put(obj, PRESENT) == null;}这个也是为什么在Set中不能像在List中一样有重复的项的根本原因,因为HashMap的key是不能有重复的。并且元素不保证顺序,可以有空值,最多有一个。LinkedHashSet:HashSet的一个子类,一个链表具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之处在于,后者维护一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到set中的顺序(插入顺序)进行迭代。注意,插入顺序不受在set中重新插入的元素影响。(如果在s.contains(e)返回true后立即调用s.add(e),则元素e会被重新插入到set  s中。)如果模块通过输入得到一个set,复制这个set,然后返回由此副本决定了顺序的结果,这种情况下这项技术特别有用。(客户通常期望内容返回的顺序与它们出现的顺序相同。)TreeSet:SortedSet的子类,通过TreeMap树结构存储来实现。所以TreeSet是有序的,HashSet是通过复写hashCode()方法和equals()方法来保证的,而HashSet通过Compareable接口的compareTo()方法来保证的。

Map总结:

编辑


Map是一个映射接口,其中的每个元素都是一个key-value键值对,同样抽象类AbstractMap通过适配器模式实现了Map接口中的大部分函数,TreeMap、HashMap、WeakHashMap等实现类都通过继承AbstractMap来实现,另外,不常用的HashTable直接实现了Map接口,它和Vector都是JDK1.0就引入的集合类。

Hashtable: 与HashMap非常相似,不所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类 是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。HashTable使用Enumeration,同步线程安全。HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。不同线程不安全,但是效率相对要高。使用迭代器遍历。WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象 中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。TreeMap: 实现这样一个映象,对象是按键升序排列的。基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。适用于按自然顺序或自定义顺序遍历键(key)。HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。Properties:Hashtable的子类,最大的不同在于所操作的键值对必须都是String,该集合较为古老,被许多Java类引用,例System.getProperties()l

Iterator是遍历集合的迭代器(不能遍历Map,只用来遍历Collection),Collection的实现类都实现了iterator()函数,它返回一个Iterator对象,用来遍历集合,ListIterator则专门用来遍历List,相对于Iterator增加可往前遍历,而Enumeration则是JDK1.0时引入的,作用与Iterator相同,但它的功能比Iterator要少,它只能再Hashtable、Vector和Stack中使用。

Arrays和Collections是用来操作数组、集合的两个工具类,例如在ArrayList和Vector中大量调用了Arrays.Copyof()方法,而Collections中有很多静态方法可以返回各集合类的synchronized版本,即线程安全的版本,当然了,如果要用线程安全的结合类,首选Concurrent并发包下的对应的集合类。