Java面试知识点2——集合

Java面试知识点2——集合

1.说一下Java中的集合有哪些?

答:从三个方面的来阐述,常见的集合、实现类以及集合的对比
(1)常见的Java集合有List、Set、Map。List和Set继承自Collection接口,而Map没有。

(2)实现类

  • List的实现类有:ArrayList、LinkedList、Vector
  • Set的实现类有:HashSet、TreeSet、LinkedHashSet
  • Map的实现类有:HashMap、TreeMap、ConcurrentHashMap、HashTable、LinkedHashMap

(3)对比

  • List有序,元素可重复;Set无序,元素不可重复;Map是键值对,键唯一。
  • ArrayList底层是数组,增删慢,查询快;LinkeList底层是链表,增删快,查询慢;Vector底层也是数组,线程安全,但效率低
  • HashSet无序,唯一,底层采用HashMap的Key保存数据;TreeSet有序,底层是红黑树。
    HashMap底层是数组+链表,数组时主体,链表是为了防止hash冲突,jdk8以后,链表长度长度超过阈值(默认8)就转化成红黑树,以减少搜索时间;TreeMap底层是红黑树,HashMap和TreeMap的线程都不安全,HashMap查询快,需要排序的时候才会用TreeMap;ConcurrentHashMap和HashTable的线程都是安全的,区别在于ConcurentHashMap效率更高,因为ConcurrentHashMap用分段锁,而HashTable用synchronize加锁。
    补充
    synchronize加锁:常用在三个地方:修饰实例方法、修饰静态方法、修饰代码块。
2.ArrayList和LinkList的区别?

答:ArrayList查询快,尾部增删快,头部增删慢,随机访问速度快;LinkList头尾增删速度快,中间不高,性能远比arraylist差,不适合做查询;
ArrayList采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响;而LinkList采用链表存储,所以插入和删除元素的时间复杂度不受元素位置的影响。

3.HashMap底层原理

答:这个和JDK的版本有点关系,JDK8以前:数组+双链表;JDK8以后:数组+双链表+红黑树

4.HashMap的resize过程是什么样的?

答:采用hash表数组加链表的形式,1.8以后引入了红黑树的数据结构,初始化数组长度为16,当数组长度到0.75时扩容,链表长度大于8时转为红黑树,红黑树的长度小于6时转为链表结构,数组中的元素容量超过了阈值的0.75就会除法库容长度。

5.HashMap和Hashtable的区别?

答:(1)HashMap去掉了HashTable的contains方法,但是加上了containsValue()和containsKey()方法。
(2)hashTable是同步的,而HashMap是非同步的,效率上比HashTable要高。
(3)HashMap允许空键值,而HashTable不允许。

6.HashMap经常在哪些地方使用?

答:(1)controller层向前台返回数据可以用map封装数据
(2)mybatis中的map可以作为参数或者封装结构

7.List、Map、Set三个接口,存取元素时,各有什么特点?

答:List:有序可重复;
Set无序不重复;
Map一般都是键值对,键唯一。

8.HashSet如何保证元素的唯一性的?

答:通过hashcode和equals方法来实现的。

9.TreeSet怎么对集合中的元素进行排序?

答:TreeSet底层数据结构是二叉树。
(1)让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法
(2)让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,覆盖compare方法。

10.map集合的两种取值方式?

答:(1)通过map.keyset,先得到map集合的键,再根据键得到value值;
(2)通过map.entrySet直接得到键值对。

11.Collection和Collections的区别?

答:(1)Collection是集合类的上级接口,继承它的接口主要有set和list
(2)Collections是工具类,有很多操作集合的方法

12.ConcurrentHashMap的工作原理及代码实现?

答:ConcurrentHashMap引入了分割(Segment)的概念,只对Map的一部分(Segment)进行上锁,这样在保证同步的时候,锁住的不是整个Map。

13.遍历一个List有哪些不同的方式?

答:(1)for循环遍历。基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。
(2)迭代器遍历,Iterator。Iterator是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。
(3)foreach循环遍历。foreach内部也是采用了Iterator的方式实现。

14.如何把一个线程不安全的集合转化为线程安全集合?

答:可以使用Collections类的synchronizedList方法,将List转化为一个线程安全的集合。
例如

List<String> list = new ArrayList<>();
List<String> synchronizedList = Collections.synchronizedList(list);

这样,可以确保不同线程在对集合进行操作时,不会产生冲突。

15.HashSet如何检查重复?HashSet是如何保证数据不可重复的?

答:(1)向HashSet中通过add()方法添加元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合equals方法比较;
(2)HashSet中的add()方法会使用HashMap的put()方法。HashMap的key是唯一的,当在HashMap中如果Key/Value相同时,会用新的Value覆盖掉旧的value值,然后返回旧的value值,所以不会重复。

16.HashMap的实现原理?

答:HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

HashMap 基于 Hash 算法实现的
(1)当我们往HashMap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
(2)存储时,如果出现hash值相同的key,此时有两种情况。

  • 如果key相同,则覆盖原始值;
  • 如果key不同(出现冲突),则将当前的key-value放入链表中

(3)获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。

17.HashMap是如何解决hash冲突的?

答:其核心就是使用了数组的存储方式,然后将冲突的key对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
需要注意的是,Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过8个之后,该链表会转为红黑树来提高查询效率,数据长度低于6之后会退化为链表。

18.为什么HashMap的初始长度是16?

答:因为长度太小很容易导致map扩容影响性能,如果分配的太大的话,又会浪费资源,所以就使用16作为初始大小。

小结:减少hash碰撞,提高map查询效率,分配过小防止频繁扩容,分配过大浪费资源。

19.什么是链表?

答:链表是可以将物理地址上不连续的数据连接起来,通过指针对物理地址进行操作,实现增删改查等功能。
链表大致分为单链表和双向链表:
**单链表:**链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,有一系列结点(地址)组成,结点可动态的生成;每个节点包含两部分,一部分存放数据变量的data,另一部分是指向下一节点的next指针(每个节点可以理解为火车的车厢,包括箱体和挂钩)。
双向链表:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

下一篇:Java面试知识点3——线程、多线程和线程池
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值