1.Java集合类
2.各集合类的比较
| 底层结构 | 是否有序 | 是否线程安全 | 特点 |
Vector<T> | Object类型的数组 | 有序 | 是线程安全 | 底层是Object数组,但它是线程安全的,性能比ArrayList差,因为很多方法都是线程同步的。可以随机访问,访问速度快。插入元素个数超过容量时,会发生自动扩张,这时会复制元素都新数组,消耗大量时间 |
ArrayList<T> | Object类型数组 | 有序 | 不是线程安全 | 底层是Object数组,不是线程安全的。可以随机访问,访问速度快。插入元素个数超过容量时,会发生自动扩张,这时会复制元素都新数组,消耗大量时间 |
LinkedList<T> | 内部静态Entry<T>类,作为链表头,Entry内部有元素值,指向上一个和下一个元素的引用。 | 有序 | 不是线程安全 | 实现了List、Deque,可以实现堆栈、队列、双端队列。插入删除速度快,查询速度慢。 |
HashSet<T> | 使用HashMap来保存元素,key就是插入的元素,value都是同一个私有静态final的Object对象 | 无序 | 不是线程安全 | 利用Object类的HashCode()方法获取某元素的hashcode,然后根据这个hashcode来算出物理地址。判断两元素是否相等利用equle,若返回true,则hashcode一定也相等。所以要重写好HashCode和equal方法。 |
TreeSet<T> | 使用TreeMap来保存元素 | 有序 | 不是线程安全 | 同上。 |
HashMap<K,T> | 使用内部静态Entry<T>类,建立一个Entry数组作为头指针。默认的负载因子是0.75,初始容量为6,极限容量为16*0.75.当总元素个数大于极限容量时,数组长度(容量)会增长两倍。(其实就是Hash表链接法,当链表长度大于规定的上限时,会转化为红黑树,这个上限默认为8) | 无序 | 不是线程安全 | 根据HashCode方法计算hashcode,从而获得数组位置,然后插入到该位置的头部(像栈一样)。负载因子为0.75是一个折中,增大可以它可以减少数组的内存占用,但会增加查询开销。迭代器遍历时,顺序为自然顺序(若有自定义顺序,则按自定义顺序)。在1.8中,resize还能保持原来队列顺序不变,而且不用重新hash,而使用了原hash值+(hash^原数组length)*原数组长度。这样会使得该位若为0,则位置不变。若为1,位置变为hash+length。 |
LinkedHashMap<K,T> | Hash表和链表结合。继承Entry<T>,在其中增加before和after引用,用于链表。也就是在原来hash表基础上,利用after和before,再加上header来维护双端队列。 | 有序 | 不是线程安全 | 是HashMap的子类,在HashMap基础上,增加了双端队列,同时可以定义顺序方式,一种为插入时的顺序,一种为最近访问从小到多的顺序, |
TreeMap<K,T> | Entry<K,V>实现的红黑树 | 有序 | 不是线程安全 | 就是一个红黑树 |
HashTable<K,T> | 同HashMap | 无序 | 线程安全 | Hashtable是基于Dictionary类的它不允许key和value为空(HashMap允许一个key为null,多个value为null)。它是线程安全的Map |
WeakHashMap<K,T> | 同HashMap,同时加上一个ReferenceQueue队列 | 无序 | 不是线程安全 | Key都是弱键,表示当这个键不再正常使用时,这个键值对就会被放到ReferenceQueue队列里,然后把队列里不用的键值对从Entry里删除。Key和value都允许为null |
IdentityHashMap<K,T> | 同hashMap | 无序 | 不是线程安全 | 判断key时,是使用”==”来判断,即判断两个key是否为同一对象。 |