每日一面系列之Java集合基础

1.讲一下List、Set、Map三者的区别

  • List存储的元素是有序,可以重复的。
  • Set存储的元素是无序,不可重复的。
  • Map是以key-value键值对的方式存储元素,key是无序不可重复的,value是无序可以重复的,每个key最多只对应一个value。

2.ArrayList和LinkedList有什么区别?

  1. 是否保证线程安全:ArrayList和LinkedList都是线程不安全的。
  2. 底层数据结构:ArrayList底层是Object数组,LinkedList底层是双向链表。
  3. 插入和删除元素操作的时间复杂度是否受元素位置的影响:ArrayList底层是采用数组方式存储元素的,所以插入和删除元素的时间复杂度是受元素位置所影响的,因为每插入火删除一个元素,其他元素的位置都会随之移动。LinkedList底层采用的是双向链表,所以插入和删除元素的时间复杂度是不受元素位置影响的。
  4. 是否支持快速随机访问:ArrayList支持快速随机访问,可以根据元素下标快速查到对应元素。LinkedList是不支持快速随机访问的,需要对链表进行遍历。
  5. 内存空间的占用: ArrayList的空 间浪费主要体现在在list列表的结尾会预留⼀定的容量空
    间,⽽LinkedList的空间花费则体现在它的每⼀个元素都需要消耗⽐ArrayList更多的空间(因
    为要存放直接后继和直接前驱以及数据)。

3. ArrayList 与 Vector 区别呢?

ArrayList 和 Vector都实现了List接口

  1. 线程安全方面:ArrayList是线程不安全的,也是线程不同步的。Vector是线程安全的,也是线程同步的。
  2. 扩容机制方面:Vector 增长原来的一倍,ArrayList 增加原来的 0.5 倍。

4.HashMap和HashTable有什么区别?

  1. 线程是否安全:HashMap是线程不安全的.HashTable是线程安全的,HashTable内部方法基本都使用了synchronized进行加锁。
  2. 效率:因为线程安全的问题,HashMap的效率要高于HashTable。
  3. key和value能否为null:HashMap最多只允许一个key为null,允许一个或者多个key对应的value为null。HashTable不允许key和value为null。
  4. 底层数据结构:HashTable底层是使用数组加链表的形式实现的。HashMap在1.8之前也是使用数组加链表的形式实现的,在1.8之后为了解决哈希冲突采用数组加链表或者数组加红黑树的形式实现。
  5. 初始容量的大小和扩容容量的大小:如果不指定初始化容量,HashMap默认是16,每次扩容为原来的2倍。HashTable默认是11,每次扩容为原来的2n+1倍。如果指定了初始化容量,HashTable会直接使用指定的容量大小,HashMap会将其扩充为2的幂次方大小,也就是说HashMap总是使用2的幂次方作为哈希表的大小。

5.HashMap和HashSet有什么关系与区别?

HashSet底层就是基于HashMap实现的。

  1. HashMap实现了Map接口,HashSet实现了Set接口。
  2. HashMap存储的是键值对,HashSet存储的是对象。
  3. HashMap通过put()方法添加元素,HashSet通过add()方法添加元素。
  4. HashMap使用key计算hashcode,HashSet使用成员对象来计算hashcode,两个对象的hashcode可能会相等,所以使用equals()方法来判断两个对象是否相等。

6.HashSet是如何检查重复的?

将对象加入HashSet的时候,HashSet首先会计算该对象的hashcode值来判断对象加入的位置,同时还会与集合中其他对象的hashcode进行比较,如果没有与之相等的hashcode,表示新增对象没有重复。如果有相等的hashcode,则会调用equals()方法来检查相等hashcode的对象是否真的相等,如果真的相等,表示新增对象重复,则不会新增成功。

7.什么是快速失败(fail-fast)?

快速失败(fail-fast) 是 Java 集合的⼀种错误检测机制。
在使⽤迭代器对集合进⾏遍历的时候,我们在多线程下操作⾮安全失败(fail-safe)的集合类可能就会触发 fail-fast 机制,导致抛ConcurrentModificationException 异常。 另外,在单线程下,如果在遍历过程中对集合对象的内容进⾏了修改的话也会触发 fail-fast 机制。

追问:为什么在遍历过程中对集合对象的内容进行修改就会触发fail-fast?

每当迭代器使⽤ hashNext()或者next() 遍历下⼀个元素之前,都会先检测 modCount 变量是否等于expectedModCount 值,是的话就返回遍历;否则抛出异常,终⽌遍历。如果我们在集合被遍历期间对其进⾏修改的话,就会改变 modCount 的值,进⽽导致 modCount不等于expectedModCount ,进⽽抛出 ConcurrentModificationException 异常。

注意:通过 Iterator 的⽅法修改集合的话会修改到 expectedModCount 的值,所以不会抛出异常。

8.什么是安全失败(fail-safe)?

采⽤安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,⽽是先复制原有集合内容,在
拷⻉的集合上进⾏遍历。所以,在遍历过程中对原集合所作的修改并不能被迭代器检测到,故不会抛
ConcurrentModificationException 异常。

注意:Arrays.asList() 将数组转换为集合后,底层其实还是数组。不能对其进行修改。

9.说一说HashSet、LinkedHashSet和TreeSet三者有什么异同?

  • HashSet是Set接口的主要实现类,HashSet底层是基于HashMap实现的,线程是不安全的,可以存储null值。
  • LinkedHashSet是HashSet的子类,可以按照添加的顺序进行遍历。
  • TreeSet底层使用红黑树,能够按照元素添加的顺序进行遍历,排序方式有自然排序也有定制排序。

10.讲一下comparable 和 Comparator 的区别

  • comparable 接⼝实际上是出⾃java.lang包,它有⼀个 compareTo(Object obj) ⽅法⽤来排序
  • comparator 接⼝实际上是出⾃java.util包,它有⼀个 compare(Object obj1, Object obj2) ⽅法⽤来排序

11.为什么集合类没有实现 Cloneable 和 Serializable 接口?

克隆 (cloning) 或者是序列化 (serialization) 的语义和含义是跟具体的实现相关的。因此,应该由集合类的具体实现来决定如何被克隆或者是序列化。

12.讲一下Collection 和 Collections 的区别。

  • collection 是集合类的上级接口, 继承与它的接口主要是 set 和 list。
  • collections 类是针对集合类的一个帮助类. 它提供一系列的静态方法对各种集合的搜索, 排序, 线程安全化等操作。

13.什么是迭代器 (Iterator)?

Iterator 接口提供了很多对集合元素进行迭代的方法。每一个集合类都包含了可以返回迭代器实例的迭代方法。迭代器可以在迭代的过程中删除底层集合的元素, 但是不可以直接调用集合的 remove(Object Obj) 删除,可以通过迭代器的 remove() 方法删除。

14.Iterator 和 ListIterator 的区别是什么?

  1. Iterator 可用来遍历 Set 和 List 集合,但是 ListIterator 只能用来遍历 List。
  2. Iterator 对集合只能是前向遍历,ListIterator 既可以前向也可以后向。
  3. ListIterator 实现了 Iterator 接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引等等。

15.为什么要使⽤集合?

当我们需要保存⼀组类型相同的数据的时候,我们应该是⽤⼀个容器来保存,这个容器就是数组,但
是,使⽤数组存储对象具有⼀定的弊端, 因为我们在实际开发中,存储的数据的类型是多种多样的,
于是,就出现了“集合”,集合同样也是⽤来存储多个数据的。数组的缺点是⼀旦声明之后,⻓度就不可变了;同时,声明数组时的数据类型也决定了该数组存储的数据的类型;⽽且,数组存储的数据是有序的、可重复的,特点单⼀。 但是集合提⾼了数据存储的灵活性,Java 集合不仅可以⽤来存储不同类型不同数量的对象,还可以保存具有映射关系的数据。

16.如何恰当的选用集合?

主要根据集合的特点来选⽤,⽐如我们需要根据键值获取到元素值时就选⽤ Map 接⼝下的集合,需要排序时选择 TreeMap ,不需要排序时就选择 HashMap ,需要保证线程安全就选⽤ConcurrentHashMap 。当我们只需要存放元素值时,就选择实现 Collection 接⼝的集合,需要保证元素唯⼀时选择实现Set 接⼝的集合⽐如 TreeSet 或 HashSet ,不需要就选择实现 List 接⼝的⽐如 ArrayList或 LinkedList ,然后再根据实现这些接⼝的集合的特点来选⽤。

17.有没女朋友,家住在哪里?

HR问你这个,主要是考查是否上班太远了,浪费时间,且容易换⼯作。个人建议,实话实说。当然如果担心因为家太远,导致与offer失之交臂(可能性比较小),那么可以考虑把距离说小一点。

特别提醒:HashMap和ArrayList是集合框架的重点,也是面试的高频考点,一般问的都比较深。这两块内容我会在后续两天单独抽出来写。

每天提升一点点,让你的面试信心满满!

猜你喜欢

转载自blog.csdn.net/w1453114339/article/details/106961744