集合
一、List、Set和Map的区别
List:1.可以允许重复的对象
2.可以插入多个Null元素
3.是一个有序容器,保持了每个元素的插入顺序,输出顺序就是插入时的顺序
4.常用实现类:ArrayList、LinkedList和Vector,ArrayList基于数组实现的,是一个动态数组,能自动扩容,默认初始值为10,每次扩容为原来的1.5倍,线程不安全;LinkedList基于双向链表实现的,插入和存取速度很快,线程不安全
Set:1.不允许重复的对象
2.无序容器,无法保证每个元素的顺序
3.只允许一个Null元素
4.常用的实现类:HashSet、LinkedHashSet 以及 TreeSet。常用的为HashSet,线程不安全,底层实现是一个HashMap,初始容量为16,加载因子为0.75,即当元素个数超过容量长度的0.75倍,进行扩容,扩容增量为原来的1倍。
Map:1.Map不是Collection的子接口或者实现类,Map是一个接口。
2.Map的每个Entry都持有两个对象,即键值对,Map可能持有相同的对象但键值对象必须是唯一的。
3.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。
4.HashMap底层实现原理:数组加链表实现的,数组是HashMap的主体,链表是为了解决哈希冲突而存在的,如果定位到的数组位置不包含链表(即当前ectry的next指向Null),查找添加会很快,仅需一次寻址就可以,如果定位到的数组包含链表,添加时,需要遍历链表,如果存在,则覆盖,否则新增;查找时,仍需遍历链表,通过key的equal方法逐一对比。
5.HashMap:可以存储Null键和Null值,初始值为16,扩容时为2的指数倍增加,线程不安全;
6.HashTable:底层为数组加链表实现,无论是键还是值都不允许为Null,初始值为11,扩容时为原来的2倍加1,线程安全,put方法是synchronized的所以可以保证其线程安全;实现线程安全的方式是在修改数据时锁住整个HashTable,效率比较低
7.ConcurretHashMap:底层采用分段数组加链表实现,线程安全,默认将Hash分为16个桶,get、put、remove等常用操作只锁住当前需要用到的桶。每次只锁住一个桶,原来只能有一个线程写入,现在可以有16个线程同时写入,并发性能明显提高。