面试补充之集合类
WeakHashMap与HashMap
WeakHashMap中的key采用的是“弱引用”的方式,只要WeakHashMap中的key不再被外部引用,所对应的键值对就可以被垃圾回收器回收。
HashMap中的key采用的是“强引用”的方式,当key不再被外部引用时,只有当这个key从HashMap中删除后,才可以被垃圾回收器回收。
HashMap和TreeMap区别
1、实现方式的区别
HashMap:基于哈希表实现。TreeMap:基于红黑树实现。
2、TreeMap能够把它保存的记录根据键排序。
3、HashMap:适用于Map中插入、删除和查找元素。
TreeMap:适用于按自然顺序或自定义顺序遍历键(key)。
HashMap通常比TreeMap快一点。
HashSet的实现原理
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成。HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();
//底层使用HashMap来保存HashSet中所有元素
private transient HashMap<E,Object>map;
//定义了一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
private static final Object PRESENT = new Object();
//默认的无参构造器,构造一个空的HashSet
//实际底层会初始化一个空的HashMap,并使用默认初始化容量为16和加载因子0.75
public HashSet(){
map = new HashMap<E,Object>();
}
public boolean add(E e){
return map.put(e, PRESENT)==null;
}
讲一下集合中的fail-fast机制
例如:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出ConcurrentModificationException异常,从而产生fail-fast机制。
产生原因:
当调用容器的iterator()方法返回Iterator对象时,把容器中包含对象的个数赋值给了一个变量expectedModCount,在调用next()方法时,会比较expectedModCount与容器中实际对象的个数是否相等,若二者不相等,则会抛出ConcurrentModificationException异常。
如果在遍历集合的同时,需要删除元素的话,可以用iterator里面的remove()方法删除元素。