HashMap 底层原理与扩容机制
问题:HashMap在JDK 1.7和1.8中有什么区别?
答案:
1. 数据结构:1.7是数组+链表;1.8是数组+链表+红黑树(当链表长度>8且数组长度>64时,链表转为红黑树)。
2. 哈希冲突解决:1.7采用头插法,1.8采用尾插法,避免多线程扩容时的死循环问题。
3. 扩容时机:1.7在插入前扩容,1.8在插入后扩容。
代码示例:
// HashMap基本使用
Map map = new HashMap<>();
map.put("key1", 1);
map.put("key2", 2);
// 获取值
Integer value = map.get("key1");
// 遍历
map.forEach((k, v) -> System.out.println(k + "=" + v));
ArrayList 与 LinkedList 选择策略
问题:何时使用ArrayList,何时使用LinkedList?
答案:
1. ArrayList:基于动态数组,支持随机访问(get/set效率高),但插入删除效率低(需移动元素)。
2. LinkedList:基于双向链表,插入删除效率高(只需修改指针),但不支持随机访问。
建议:大多数场景下优先使用ArrayList,因为现代CPU缓存命中率更高,且频繁扩容带来的性能损耗通常小于LinkedList的指针操作开销。仅在需要频繁在列表头部或中部插入删除元素时使用LinkedList。
CopyOnWriteArrayList 应用场景
问题:什么是CopyOnWrite容器?适用于什么场景?
答案:
CopyOnWrite容器即写时复制的容器。当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。
适用场景:读多写少的并发场景。如注册监听器列表。由于写操作涉及数组拷贝,性能较差,不适合高频写操作。