Java集合相关面试题总结

一、简介

Java集合类是我们日常编程中使用较多的一个,常见的有:ArrayList、LinkedList、HashMap、HashSet、ConcurrentHashMap、LinkedBlockQueue等等,集合类同时也是面试时必问的一项技能,所以我们有必要了解一些常见的面试题,本文将总结一部分比较常遇到的集合相关的面试题,希望可以帮助到大家。

二、集合相关面试题

【a】集合类继承图

上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。

简单说明:

  • Collection接口是所有集合类的根接口,主要的实现类有List、Set和Queue,注意Map并不是Collection的子接口,Map是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。
  • Iterator:所有集合类都实现了Iterator接口,主要用于遍历集合中的元素,主要方法:
  • hasNext():判断集合中是否还有下一个元素;next():返回当前元素的下一个元素      remove():删除当前元素

【b】请简单介绍一下List、Map和Set?

集合类 是否有序 是否可重复
List 元素有序 元素可以重复
Map 键值对方式存储元素 Map中的键唯一,不可重复,但值可以重复
Set 元素无序 元素不可重复

文字描述:

1、List:List集合存放的对象是有序的,同时也是可以重复的。List查询效率相对快一些,往List集合插入或者删除元素,由于会涉及到移动元素的成本,速度相对慢一些。

2、Set:Set集合存放的对象是无序,不能重复的。

3、Map:Map集合中的元素都是以键值对的方式进行存储的,键是唯一的,不可以重复,但是值可以重复。

【c】请简单说明一下ArrayList和LinkedList的区别?

区别 ArrayList LinkedList
底层数据结构 ArrayList底层是基于数组实现的,涉及到很多的数组拷贝,移动等操作。 LinkedList底层是基于链表实现的,通过修改链表的指向来达到元素的插入、删除等。
插入/删除效率 ArrayList由于插入、删除时需要移动元素,所以速度较慢 LinkedList直接通过修改链表的指向,断开链表等操作实现插入、删除,所以速度很快。
查询效率 ArrayList直接通过数组的下标就可以找到对应的元素,所以查询速度很快 LinkedList由于需要遍历链表,挨个进行比较,所以速度较慢
适用场景 查询多,插入、删除、更新比较少的场景 查询少,插入、删除、更新比较多的场景

【d】请简单说明一下HashMap、Hashtable、ConcurrentHashMap、LinkedHashMap、TreeMap类?

区别 HashMap Hashtable ConcurrentHashMap LinkedHashMap TreeMap
说明

HashMap是根据键的HashCode值计算出元素在bucket[]桶数组中的索引下标,访问效率很高。遍历时,取得数据的顺序是完全随机的。

因为HashMap键是不可以重复的,所以HashMap最多只允许一条记录的键为Null,允许多条记录的值为Null,是非同步的,线程不安全。

Hashtable与HashMap类似,是HashMap的线程安全版,它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢,它继承自Dictionary类,不同的是它不允许记录的键或者值为null,同时效率较低。 线程安全,并且锁分离。JDK1.7中ConcurrentHashMap内部使用分段锁机制(Segment)来表示这些不同的部分,每个段其实就是一个小的hash table,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。在JDK1.8中废弃了分段锁,采用Sychronized+CAS方式实现安全控制。 LinkedHashMap保存了记录的插入顺序,在用Iteraor遍历LinkedHashMap时,先得到的记录肯定是先插入的,在遍历的时候会比HashMap慢。 TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序(自然顺序),也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的记录是排过序的。不允许key值为空,非同步的;

【e】请谈一下Vector和ArrayList的区别?

区别 Vector ArrayList
底层数据结构 基于数组实现 基于数组实现
是否线程安全 由于加入了同步机制,所以线程安全 线程不安全
效率 由于加入了Synchronized同步机制,所以效率相对慢一些 效率相对快一些

【f】集合框架中的泛型有什么优点?

  Java1.5引入了泛型,所有的集合接口和实现都大量地使用泛型。泛型允许我们为集合指定一个可以容纳的对象类型,因此,如果你添加其它类型的任何元素,它会在编译时报错。这避免了在运行时出现ClassCastException,因为你将会在编译时得到报错信息。泛型也使得我们不需要使用显式转换和instanceOf操作符。它也给运行时带来好处,因为不会产生类型检查的字节码指令。

【g】简单说明一下集合中的快速失败机制(fail-fast)?

每次我们尝试获取下一个元素的时候,Iterator fail-fast机制都会去检查当前集合结构里的任何改动。如果发现任何改动,它抛出ConcurrentModificationException并发修改异常。Collection中所有Iterator的实现都是按fail-fast来设计的。

【h】HashMap的工作原理?

可以参考另外一篇博文,里面详细介绍了其工作原理:【https://blog.csdn.net/Weixiaohuai/article/details/103882258

【i】请谈谈hashCode()和equals()方法的重要性?

HashMap利用key对象的hashCode()和equals()方法去计算元素在数组中的索引下标。当我们从HashMap中获取值时,如果这些方法没有被正确地实现,在这种情况下,两个不同Key也许会产生相同的hashCode()和equals()输出,HashMap将会认为它们是相同的,然后覆盖它们,而非把它们存储到不同的地方。同样的,所有不允许存储重复数据的集合类都使用hashCode()和equals()去查找重复,所以正确实现它们非常重要。equals()和hashCode()的实现应该遵循以下规则:

  • (1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的;
  • (2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true;

【j】请简单说明一下Array和ArrayList有何区别?

区别 Array ArrayList
容纳对象类型  Array可以容纳基本类型和对象 ArrayList只能容纳对象
大小 Array是指定大小的 ArrayList大小是可以扩容的
适用场景 大小固定的集合时可以考虑使用数组Array 当大小动态变化时考虑使用ArrayList

【k】Collections类是什么?

Java.util.Collections是一个工具类仅包含静态方法,它们操作或返回集合。它包含操作集合的多态算法,返回一个由指定集合支持的新集合和其它一些内容。这个类包含集合框架算法的方法,比如折半搜索、排序、混编和逆序等。

【l】Comparable和Comparator接口是什么?

如果我们想使用Array或Collection的排序方法时,需要在自定义类里实现Java提供Comparable接口。Comparable接口有compareTo(T OBJ)方法,它被排序方法所使用。我们应该重写这个方法,如果“this”对象比传递的对象参数更小、相等或更大时,它返回一个负整数、0或正整数。

但是,在大多数实际情况下,我们想根据不同参数进行排序,需要使用Comparator接口,因为Comparable.compareTo(Object o)方法实现只能基于一个字段进行排序,我们不能根据对象排序的需要选择字段。

Comparator接口的compare(Object o1, Object o2)方法的实现需要传递两个对象参数,若第一个参数比第二个小,返回负整数;若第一个等于第二个,返回0;若第一个比第二个大,返回正整数。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章