集合
ArrayList 与 Vector 区别
ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
LinkedList是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。另外,他还提供了List接口中没有定义的方法,专门用于操作表头和表尾元素,可以当作堆栈、队列和双向队列使用。
ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。
Vector提供indexOf(obj, start)接口,ArrayList没有。
Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。
HashMap 和 Hashtable 的区别
HashMap 不是线程安全的
HashMap 是 map 接口的实现类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap 允许 null key 和 null value,而 HashTable 不允许。
HashTable 是线程安全 Collection。
HashMap 是 HashTable 的轻量级实现,他们都完成了Map 接口,主要区别在于 HashMap 允许 null key 和 null value,由于非线程安全,效率上可能高于 Hashtable。
区别如下:
HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因为 contains 方法容易让人引起误解。
HashTable 继承自 Dictionary 类,而 HashMap 是 Java1.2 引进的 Map interface 的一个实现。
HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须为之提供外同步。
Hashtable 和 HashMap 采用的 hash/rehash 算法都大概一样,所以性能不会有很大的差异。
HashSet 和 HashMap 区别
*HashMap* *HashSet*
HashMap实现了Map接口 HashSet实现了Set接口
HashMap储存键值对 HashSet仅仅存储对象
使用put()方法将元素放入map中 使用add()方法将元素放入set中
HashMap中使用键对象来计算hashcode值 HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false
HashMap比较快,因为是使用唯一的键来获取对象 HashSet较HashMap来说比较慢
HashMap 和 ConcurrentHashMap 的区别
Hashmap的key和value都可以为null, 是非线程安全的,存储的是键值对;
hashmap是基于哈希的原理,put存入键值对时,会对键调用 hashCode()方法,返回的hashcode用于找到bucket位置来存储Entry对象,hashMap是在bucket中储存键对象和值对象。当两个对象的hashcode相同时,代表他们的bucket位置相同,此时会发生“碰撞”。因为hashmap 是使用链表存储对象,所以这个对象会存储在链表中。那么两个对象的hashcode相同时,get方法获取对象是如何操作的呢?会根据键值找到bucket存储位置,在遍历链表调用keys.equals()找到链表中正确的节点,最终找到要找的值对象。(这里能够遍历获取正确的值是因为链表中存储的是键值对)
通过采用合适的equal()和hashcode()将会减少碰撞的发生,提高效率。
hashmap默认的负载因子大小是0.75,即当一个map填满了75%的bucket时,和其他集合(如Arraylist)一样,将会创建原来hashmap大小的两倍的bucket数组,来重新调整map的大小。并将原来的对象放入新的bucket数组中。在重新调整hashmap大小中存在哪些问题呢?在多线程条件下会存在条件竞争。因为如果两个线程都发现HashMap需要重新调整大小了,他们就会同时试着调整大小。在调整大小的过程中,存储在链表中的元素次序会反过来,因为移动到新的bucket位置时,hashmap并不会将元素放在链表的尾部,而是放在头部,如果条件竞争了,就会死循环。所以多线程慎用hashmap。所以concurrentHashmap应运而生。
————————————————