JAVA集合(面试题)

集合分为两种,单列集合(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全套面试题不讲一句废话,持续更新中.....

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值