集合面试题
1、说说常见的集合有哪些吧?
1、Collection接口的子接口包括:Set接口和List接口
2、Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
3、Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
4、List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
2、ArrayList,LinkedList,Vector这三者有什么关系和区别?
Array List:采用的是数组的方式进行存储数据的,查询和修改速度快,但是增加和删除速度慢;线程不同步。
LinkedList:采用的是链表的方式进行存储数据的,查询和修改速度慢,但是增加和删除速度快。线程不同步。
Vector:Vector非常类似ArrayList,同样使用数组方式存储数据,但是Vector是同步的。但由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差。
3、请问set/HashSet和List/ArrayList有什么区别?
List,Set 都是继承自 Collection 接口。
特点:List :元素有放入顺序,元素可重复。Set :元素无放入顺序,元素不可重复,重复元素会覆盖掉。
对比:Set:检索指定的元素效率高,删除和插入效率高,插入和删除可能会引起元素位置改变。List:和数组类似,List 可以动态增长,查找指定的元素效率低,插入删除指定的元素效率低,可能会引起其他元素位置改变。
4、面试题: 请问“==”和equals有什么区别?
错误的说法:“==”判断的是地址,equals判断的是内容(字符序列)。
如果问题是String的“==”和equals区别,则给出上面的回答,然后再给出下面的解释。
回答:“”判断的是栈中的内容,基本类型在栈中存储了引用和值,所以“”可以判断基本类型的值。 引用类型在栈中存储的是引用(地址),所以引用类型使用“”判断的就是栈中的引用(地址)。 equals方法是Object申明的,默认所有的类型都有equals方法。equals默认也是通过""判断两个元素 是否相同的,如果重写了equals则按照重写的规则判断,比如String就是判断两个对象的字符序列。
5、HashMap和Hashtable的区别
从存储结构和实现来讲基本上都是相同的,都是实现Map接口
同步性:HashMap是非同步的,Hashtable是同步的。
是否允许为null:HashMap允许为null,Hashtable不允许为null。
contains方法:Hashtable有contains方法,HashMap把Hashtable的contains方法去掉了,改成了containsValue和containsKey
继承不同:HashMap<K,V> extends AbstractMap<K,V>
public class Hashtable<K,V> extends Dictionary<K,V>
线程安全:HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized
修饰。
6、Collection和Collections的区别
Collection是集合的上级接口,继承它的有Set和List接口
Collections是集合的工具类,提供了一系列的静态方法对集合的搜索、查找、同步等操作
7、ArrayList,LinkedList的存储性能和特性
首先,ArrayList的底层是数组,LinkedList的底层是双向链表。
1、ArrayList它支持以角标位置进行索引出对应的元素(随机访问),而LinkedList则需要遍历整个链表来获取对应的元素。因此一般来说ArrayList的访问速度是要比LinkedList要快的
2、ArrayList由于是数组,对于删除和修改而言消耗是比较大(复制和移动数组实现),LinkedList是双向链表删除和修改只需要修改对应的指针即可,消耗是很小的。因此一般来说LinkedList的增删速度是要比ArrayList要快的
8、ListIterator有什么特点
ListIterator继承了Iterator接口,它用于遍历List集合的元素。
ListIterator可以实现双向遍历,添加元素,设置元素
9、如何决定选用 HashMap 还是 TreeMap?
对于在 Map 中插入、删除和定位元素这类操作,建议使用HashMap 。
假如你需要对一个有序的 key 集合进行遍历, TreeMap 是更好的选择。
10、我们能否使用任何类作为 Map 的 key?
我们可以使用任何类作为 Map 的 key ,然而在使用它们之前,需要考虑以下几点:
1、如果类重写了 equals 方法,它也应该重写 hashcode 方法。
2、类的所有实例需要遵循与 equals 和 hashcode 相关的规则。
3、如果一个类没有使用 equals ,你不应该在 hashcode 中使用它。
4、用户自定义 key 类的最佳实践是使之为不可变的,这样,hashcode 值可以被缓存起来,拥有更好的性能。不可变的类也可以确保hashcode 和 equals 在未来不会改变,这样就会解决与可变相关的问题了。
11、HashMap 的工作原理是什么?
HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。
12、集合框架底层数据结构总结
Collection
1、List
1、Arraylist: Object数组
2、Vector: Object数组
3、LinkedList: 双向循环链表
2、 Set
1、HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素
2、LinkedHashSet: LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。
3、TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树。)
3、Map
1、HashMap: JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间
2、LinkedHashMap: LinkedHashMap 继承自 HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红黑树组成。另外,LinkedHashMap 在上面结构的基础上,增加了一条双向链表,使得上面的结构可以保持键值对的插入顺序。同时通过对链表进行相应的操作,实现了访问顺序相关逻辑。
3、HashTable: 数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的
4、TreeMap: 红黑树(自平衡的排序二叉树)