集合面试题整理

1. 常用集合类都有什么?

  • Map和Collection是所有集合框架的父接口
  • Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
  • Collection接口的子接口包括:Set接口和List接口
  • Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
  • List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等

2. List,Set,Map三者的区别?

  • List:有序(元素存取的顺序一致),元素可重复,可插多个null元素,元素都有索引。
  • Set:无序(存取顺序可能不一致),元素不可重复,只允许存入一个null元素,必须保证元素唯一性。
  • Map:键值对集合, Key无序,唯一;value 不要求有序,允许重复。

3. 关于快速失败机制 “fail-fast”?

  • 是java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生 fail-fast 机制。
  • 产生原因:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modCount变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常( ConcurrentModificationException ),终止遍历。

4. 快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?

  • 快速失败:当你在迭代一个集合的时候,如果有另一个线程正在修改你正在访问的那个集合时,就会抛出一个 ConcurrentModification 异常。 在 java.util 包下的都是快速失败。
  • 安全失败:你在迭代的时候会去底层集合做一个拷贝,所以你在修改上层集合的时候是不会受影响的,不会抛出 ConcurrentModification 异常。在 java.util.concurrent 包下的全是安全失败的。

5. 集合框架底层数据结构?

Collection

  • Arraylist:数组
  • Vector: 数组
  • LinkedList: 双向循环链表
  • HashSet(无序,唯一):基于 HashMap,底层采用 HashMap 来保存元素
  • LinkedHashSet:继承于HashSet,内部是通过 LinkedHashMap 来实现
  • TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)

Map

  • HashMap: JDK1.8前由数组+链表组成(“拉链法”解决冲突),JDK1.8后链表长度大于阈值(默认为8)时,将链表转化为红黑树。
  • LinkedHashMap:继承自 HashMap,底层基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
  • HashTable: 数组+链表
  • TreeMap: 红黑树(自平衡的排序二叉树)

6. Iterator 和 ListIterator 有什么区别?

  • Iterator 可以遍历 Set 和 List 集合,ListIterator 只能遍历 List。
  • Iterator 只能单向遍历,ListIterator 可以双向遍历。
  • ListIterator 实现 Iterator 接口,增加了一些额外的功能。

7.HashMap解决哈希冲突的方式有什么?

  • 使用链地址法(使用散列表)来链接拥有相同hash值的数据
  • 使用2次扰动函数(hash函数)来降低哈希冲突的概率,使得数据分布更平均
  • 引入红黑树进一步降低遍历的时间复杂度,使得遍历更快

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

  • for 循环遍历,基于计数器。在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后停止。
  • 迭代器遍历,Iterator。Iterator 是面向对象的一个设计模式,目的是屏蔽不同数据集合的特点,统一遍历集合的接口。Java 在 Collections 中支持了 Iterator 模式。
  • foreach 循环遍历。foreach 内部也是采用了 Iterator 的方式实现,使用时不需要显式声明 Iterator 或计数器。优点是代码简洁,不易出错;缺点是只能做简单的遍历,不能在遍历过程中操作数据集合,例如删除、替换。

9. 能否使用任何类作为 Map 的 key?

可以,但是需要特定的条件:

  • 类重写了 equals() 方法和hashCode() 方法
  • 类的所有实例遵循与 equals() 和 hashCode() 相关的规则
  • 类没有使用 equals(),则 hashCode() 中也不使用
  • 类最好的不可变的,否则可能会产生同一键(对等的两个对象)存在两个地方的问题,或者可以存在重复键值的假象。

10. Collections 工具类中的 sort()方法如何比较元素?

Collections 工具类的 sort 方法有两种重载的形式,

  • 第一种要求传入的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较;

  • 第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java 中对函数式编程的支持)。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值