集合分为两种,单列集合(collection)和双列集合(map)
一.单列集合(collection)分为:list、set、queue(不常用,可以省略)
1.list:允许元素重复,有序,可以允许多个null元素,会引出arraylist和linkedlist区别问题
ArrayList:存储结构为数组,内存内连续存储,所以适合随机访问(get/set),线程不安全
LinkedList:存储结构为链表,内存内分散存储,所以适合插入、删除操作,线程不安全
Vector:存储结构为数组,查询快,增删满,线程安全,效率低不建议使用,
2.set:不允许元素重复,无序,只允许一个null元素,做内部排序
HashSet:基于HashMap来实现的,底层为哈希表(查询速度快):无序,存储和取出元素的顺序可能不同,不允许存储重复元素,但允许有null值,没有get方法,所以不能使用普通for循环遍历
LinkedHashSet:底层为哈希表(数组+链表+红黑树)+链表:多一条链表来记录元素的存储顺序,保证元素有序,元素值不能重复
TreeSet:Treeset底层实际上是一个TreeMap,数据结构为自平衡二叉树,向集合中放入元素等于放入了TreeMap的key部分。虽然无序,不可重复,但可以按照元素大小顺序自动排序,所以TreeMap是一个可排序集合(有序集合)
3.queue:队列,先进后出,适合插入、提取、验证等操作(博主没被问过,所以没总结QAQ)
二.双列集合(Map)使用键值对“Key-Value映射存储数据,Key值唯一不能重复,Value可重复
分为:HashMap(重点)、HashTable(重点)、TreeMap、ConCurrentHashMap(重点)、LinkedHashMap
1.HashMap:底层为数组+链表+红黑树,线程不安全
HashMap底层原理:jvm存储时通过key来决定每一个entry的槽位,value以链表的形式挂在对应槽位上,如果长度大于8则转为红黑树,默认初始化容量为16,达到阈值扩容(阈值=最大容量*0.75(负载因子)),扩容每次两倍,原理是使用一个容量更大的数组替代原本的数组,transfer()方法将原有的Entry数组的元素拷贝到新的Entry数组里。
HashMap的put原理:在使用put方法的时候会传入key和value参数,put方法会去判断这个hashmap是否为null或者长度是否为0,如果是就新建一个,然后会根据key计算hash码获取数组位置,再继续判断这个数组下标是否为null,为null则直接插入value值,否则就判断key是否为null,当key!=null就覆盖value值,再判断数组后面跟着的链表是否为树,是树就传入key-value格式存入,如果是链表,那put方法就遍历这个链表,在遍历的时候判断这个链表的长度是否大于8,大于就把链表转换为树,再按照key-value的格式存入,小于就判断链表内的key!=null,如果key!=null则覆盖,如果key为null的话,value就会插入,最后判断是否需要扩容,当数组容量超过阈yu值,则会扩容--即翻倍
注:(被问到过put很多次...)
2.HashTable:底层是数组+链表,线程安全,不允许key和value为null
注:一般会问和hashmap的区别,博主以这个角度去分析
HashMap与HashTable的区别:
1.hashmap线程不安全,hashtable线程安全
2.hashmap性能高于hashtable,多线程建议使用hashmap
3.hashmap的数据结构是数组+链表/红黑树,hashtable数据结构是数组+链表
4.hashmap允许key和value为null,hashtable不允许
5.hashmap初始容量是16,扩容x2,hashtable初始容量是11,扩容x2+1
6.计算hash的方法不同,hashtable是直接用key的hashcode对table数组的长度直接取模,而hashmap的hash对key的hashcode进行二次hash,再对table数组长度取模
3.TreeMap:有序,二叉排序树(没被问过)
4.ConCurrentHashMap:HashMap的线程安全版
采用分段锁,底层结构是Node数组+链表+红黑树,采用CAS和 synchronized 来实现线程安全
和HashMap的区别就是:是HashMap的线程安全版
5.LinkedHashMap(扩展HashMap类,有序,线程不安全,键值可为null)
扩展:Hashcode和equals的区别:
1.如果两个对象相同,那么它们的hashCode值一定要相同
2.如果两个对象的hashCode相同,它们并不一定相同(这里说的对象相同指的是用eqauls方法比较)。
如不按要求去做了,会发现相同的对象可以出现在Set集合中,同时,增加新元素的效率会大大下降。
3.equals()相等的两个对象,hashcode()一定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。
或
1、equals方法用于比较对象的内容是否相等(覆盖以后)
2、hashcode方法只有在集合中用到
3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
4、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。
关注,java全套面试题不讲一句废话,持续更新中.....