科百科
当前位置: 首页 范文大全

java集合面试题总结及答案(java集合框架详解)

时间:2023-06-12 作者: 小编 阅读量: 7 栏目名: 范文大全

java集合框架详解本章节主要分享一些Java中的集合在面试中常问的高频问题,这里给出的是相对比较简略的答案,不过针对面试的回答,这些就足够了,另外就是一定要加入自己的个人理解,不要背书形式的回答1.Java中的集合框架。

本章节主要分享一些Java中的集合在面试中常问的高频问题,这里给出的是相对比较简略的答案,不过针对面试的回答,这些就足够了,另外就是一定要加入自己的个人理解背书形式的回答。

1.Java中的集合框架有哪些?

回答:Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。

Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、TreeMap、LinkedHashMap 等等。

2.ArrayList和LinkedList的底层实现和区别?

回答:ArrayList底层使用的是 Object数组;LinkedList底层使用的是 双向链表 数据结构。

ArrayList:增删慢、查询快,线程不安全,对元素必须连续存储。

LinkedList:增删快,查询慢,线程不安全。

追问:说说ArrayList的扩容机制?

回答:通过阅读ArrayList的源码我们可以发现当以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。当插入的元素个数大于当前容量时,就需要进行扩容了, ArrayList 每次扩容之后容量都会变为原来的 1.5 倍左右

3.HashMap的底层实现?扩容?是否线程安全?

回答:在jdk1.7之前HashMap是基于数组和链表实现的,而且采用头插法。

而jdk1.8 之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。采用尾插法。

HashMap默认的初始化大小为 16。当HashMap中的元素个数之和大于负载因子*当前容量的时候就要进行扩充,容量变为原来的 2 倍。(这里注意不是数组中的个数,而且数组中和链/树中的所有元素个数之和!)

注意:我们还可以在预知存储数据量的情况下,提前设置初始容量(初始容量 = 预知数据量 / 加载因子)。这样做的好处是可以减少 resize() 操作,提高 HashMap 的效率

美团面试的时候问到这个问题,还给出具体的值,让我算出初始值设置为多少合适?

HashMap是线程不安全的,其主要体现:

1.在jdk1.7中,在多线程环境下,扩容时会造成环形链或数据丢失。

2.在jdk1.8中,在多线程环境下,会发生数据覆盖的情况。

追问:HashMap扩容的时候为什么是2的n次幂?

回答:数组下标的计算方法是(n-1)& hash,取余(%)操作中如果除数是2的幂次则等价于与其除数减一的与(&)操作(也就是说 hash%length==hash&(length-1)的前提是 length 是2的 n 次方;)。 并且采用二进制位操作 &,相对于%能够提高运算效率,这就解释了 HashMap 的长度为什么是2的幂次方。

追问:HashMap的put方法说一下。

回答:通过阅读源码,可以从jdk1.7和1.8两个方面来回答

1.根据key通过哈希算法与与运算得出数组下标

2.如果数组下标元素为空,则将key和value封装为Entry对象(JDK1.7是Entry对象,JDK1.8是Node对象)并放入该位置。

3.如果数组下标位置元素不为空,则要分情况

(i)如果是在JDK1.7,则首先会判断是否需要扩容,如果要扩容就进行扩容,如果不需要扩容就生成Entry对象,并使用头插法添加到当前链表中。

(ii)如果是在JDK1.8中,则会先判断当前位置上的TreeNode类型,看是红黑树还是链表Node

​ (a)如果是红黑树TreeNode,则将key和value封装为一个红黑树节点并添加到红黑树中去,在这个过程中会判断红黑树中是否存在当前key,如果存在则更新value。

​ (b)如果此位置上的Node对象是链表节点,则将key和value封装为一个Node并通过尾插法插入到链表的最后位置去,因为是尾插法,所以需要遍历链表,在遍历过程中会判断是否存在当前key,如果存在则更新其value,当遍历完链表后,将新的Node插入到链表中,插入到链表后,会看当前链表的节点个数,如果大于8,则会将链表转为红黑树

​ (c)将key和value封装为Node插入到链表或红黑树后,在判断是否需要扩容,如果需要扩容,就结束put方法。

追问:HashMap源码中在计算hash值的时候为什么要右移16位?

回答:我的理解是让元素在HashMap中更加均匀的分布,具体的可以看下图,下图是《阿里调优手册》里说的。

4.Java中线程安全的集合有哪些?

Vector:就比Arraylist多了个同步化机制(线程安全)。

Hashtable:就比Hashmap多了个线程安全。

ConcurrentHashMap:是一种高效但是线程安全的集合。

Stack:栈,也是线程安全的,继承于Vector。

追问:说一下ConcurrentHashMap的底层实现,它为什么是线程安全的?

回答:在jdk1.7是 分段的数组+链表 ,jdk1.8的时候跟HashMap1.8的时候一样都是基于数组+链表/红黑树。

ConcurrentHashMap是线程安全的

(1)在jdk1.7的时候是使用分段所segment,每一把锁只锁容器其中一部分数据,多线程访问容器里不同数据段的数据,就不会存在锁竞争,提高并发访问率。

(2)在jdk1.8的时候摒弃了 Segment的概念,而是直接用 Node 数组+链表+红黑树的数据结构来实现,并发控制使用 synchronizedCAS 来操作。synchronized只锁定当前链表或红黑二叉树的首节点。

5.HashMap和Hashtable的区别

回答:

(1)线程是否安全: HashMap 是非线程安全的,HashTable 是线程安全的,因为 HashTable 内部的方法基本都经过synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!);

(2)对 Null key 和 Null value 的支持: HashMap 可以存储 null 的 key 和 value,但 null 作为键只能有一个,null 作为值可以有多个;HashTable 不允许有 null 键和 null 值,否则会抛出 NullPointerException。

(3)初始容量大小和每次扩充容量大小的不同 : ① 创建时如果不指定容量初始值,Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap 默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 HashMap 会将其扩充为 2 的幂次方大小(HashMap 中的tableSizeFor()方法保证,下面给出了源代码)。也就是说 HashMap 总是使用 2 的幂作为哈希表的大小,后面会介绍到为什么是 2 的幂次方。

(4)底层数据结构: JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)(将链表转换成红黑树前会判断,如果当前数组的长度小于 64,那么会选择先进行数组扩容,而不是转换为红黑树)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

(5)效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。另外,HashTable 基本被淘汰,不要在代码中使用它;

6.HashMap和TreeMap的区别?

回答:

1、HashMap是通过hash值进行快速查找的;HashMap中的元素是没有顺序的;TreeMap中所有的元素都是有某一固定顺序的,如果需要得到一个有序的结果,就应该使用TreeMap;

2、HashMap和TreeMap都是线程不安全的;

3、HashMap继承AbstractMap类;覆盖了hashcode() 和equals() 方法,以确保两个相等的映射返回相同的哈希值;

TreeMap继承SortedMap类;它保持键的有序顺序;

4、HashMap:基于hash表实现的;使用HashMap要求添加的键类明确定义了hashcode() 和equals() (可以重写该方法);为了优化HashMap的空间使用,可以调优初始容量和负载因子;

TreeMap:基于红黑树实现的;TreeMap就没有调优选项,因为红黑树总是处于平衡的状态;

5、HashMap:适用于Map插入,删除,定位元素;

TreeMap:适用于按自然顺序或自定义顺序遍历键(key)

    推荐阅读
  • 豪横大狗(六畜兴旺狗)

    嘶吼着叫大丫起床,离她上学迟到只有半个小时,离我上班迟到还有一个半小时。送大丫去学校的路上,拐弯经过派出所上坡的时候,大丫在后面慢悠悠地说她想养一只狗。大丫小时候我带着她吃狗肉,美其名曰“狗肉滚一滚,神仙站不稳”;其一:现在的居住条件本来就不适合养狗的。直到学校门口大丫还在自言自语描述着她心目中狗的品种和如何可爱,我全程三缄其口。狗摇尾乞怜,至少可以解决温饱。

  • 汤圆的做法家常做法(学会在家做料足又放心)

    下面内容希望能帮助到你,我们来一起看看吧!汤圆的做法家常做法准备主料:花生仁70克,核桃仁30克,糯米粉100克。花生仁70克,核桃30克,小火翻炒至变色。花生仁、核桃去皮,倒入破壁机,再加入15克黑芝麻,打成粉。加入红糖10克,搅拌均匀,加入糯米粉100克,搅拌成絮状,揉成面团,醒发30分钟。将汤圆馅搓圆,汤圆皮搓圆,将汤圆皮捏成薄片,将馅包在里面收口搓圆。锅中清水煮沸,倒入汤圆,中火煮至汤圆飘起。

  • lg电视用网络如何看电视直播(LG电视怎么看电视直播)

    四、再返回主界面,找到“应用助手”—读取“USB”的内容。

  • 企业三八节祝福语(常用节日祝福语)

    企业三八节祝福语?下面希望有你要的答案,我们一起来看看吧!企业三八节祝福语星星闪烁着为你舞蹈,月亮微笑着为你祝福,在这欢乐的时刻,我想悄悄的对你说:妇女节日快乐!向天下所有的女士致敬。今天是一年一度的妇女节啦,在这里恭祝所以女性健康快乐靓丽多姿!给自己心情放个假,烦恼压力都放下;给自己生活放个假,闲事琐事别管它;给自己劳务放个假,锅碗瓢盆老公刷。若问你要干什么?今天只管乐哈哈!

  • 丰田塞纳商务车七座(丰田塞纳MPV商务车)

    丰田塞纳外观采用了一体化设计,晶钻式大灯充满时尚感;前脸为子弹头式,从而有效地减小了风阻系数。丰田塞纳融入了丰田家族的全新设计语言,前脸造型更加宽厚,焕然一新的进气格栅与新的前大灯造型融会贯通,一气呵成。丰田塞纳商务车第二排配备了双真皮座椅,并且每个座椅都配备了腿部支撑功能。塞纳标配了6气囊和ABS、ESP等安全配置。另外,塞纳可以提供2个截然不同的第2排座椅选择。

  • 搬砖幽默句子(关于搬砖的搞笑句子)

    搬砖幽默句子年轻的时候,努力搬砖,是为了自己可以优雅的老去。今晚和那个渣男李吵了架后,和朋友出去吃了一顿田螺煲,罪过呀,虽然现在也有人追,但是还是要继续减肥,为了能遇到更好的男人。崇光真的爱林萧,他变成陆烧只是换了个方式爱她。令人信服的往往不是说话者的语言,而是说话者的神情。没有什么是可以击垮我的,但愿如自己所愿圆满最好,努力吧,继续努力搬砖。心简单,世界就简单,幸福才会生长。

  • 吃药能吃萝卜吗(吃药的时候能不能吃萝卜)

    大凡体质虚寒之人需要补养,补养用温热药,白萝卜性属寒凉,则不宜食之;因药与食之热寒相抵,其效自失。要提醒的是,白萝卜不适合脾胃虚弱者,如大便稀者,应减少使用,还有值得注意的是在服用参类滋补药时忌食本品,以免影响疗效。萝卜含有丰富的维生素,与药物之间没有相克的情况,也不会降低药物的疗效,喝西药期间吃萝卜是没有太大的影响的,只要间隔三十分钟后吃,一般没有什么大问题。另外,吃药期间多喝水,促进新陈代谢。

  • 口罩多久换一次 一次性医用口罩多久换一次

    N95口罩是专业的医用防护口罩,N95口罩的过滤效率达到95%,一般用于医护人员,N95口罩无具体的使用时间。建议:当N95口罩的任何部件出现破损、断裂和丢失如鼻夹、鼻夹垫,以及明显感觉呼吸阻力增加时,应废弃整个N95口罩。一次性口罩一般建议使用时效是6-8个小时,条件不允许的话一天一换也是可行的,重复性使用可能会滋生细菌,环境有粉尘或者空气污染、传染病的话尤其要注意及时更换口罩。

  • 大蒜炒鸡杂如何做(简介大蒜炒鸡杂如何做)

    下面更多详细答案一起来看看吧!大蒜炒鸡杂如何做大蒜洗好,切好,根与叶稍微分一下。鸡胗洗好,切片,再清洗好。把锅烧热,加入适量的油。油加热后,先放点生姜丝入油锅炸一下,有一点黄就把鸡杂倒入翻炒。炒好后就可以了。

  • 二氧化氯作消毒剂利用什么性(高效消毒灭菌剂)

    美国环保局将二氧化氯作为替代液氯的首选消毒剂,并对二氧化氯用于饮用水消毒做了具体规定。对杀灭异养菌所需的ClO2浓度仅为Cl2的1/2。ClO2对地表水中大肠杆菌杀灭效果比Cl2高5倍以上。ClO2对病毒的灭活比O3和Cl2更有效。无毒、无刺激急性经口毒性试验表明,二氧化氯消毒灭菌剂属实际无毒级产品,积累性试验结论为弱蓄积性物质。