分区 总结整理 的第 7 页
• 1.查询插入等用途(顺序性):在 Map 中插入、删除和定位元素,HashMap 适合;若要按顺序遍历键,则 TreeMap 适合。
• 2.底层优化:HashMap 可以调优初始容量和负载因子;TreeMap 没有调优选项,因为树总处于平衡状态。
• 3.实现接口:都实现了 Cloneable 接口。HashMap 继承 AbstractMap;TreeMap 实现 SortMap 接口,能够把它保存的记录根据键排序(默认按键的升序)。
• 4.底层实现:HashMap 底层是数组+链表法;TreeMap 底层是数组+红黑树。(从 Java 8 开始,HashMap,ConcurrentHashMap 和 LinkedHashMap 在处理频繁冲突时将使用平衡树
来代替链表,当同一 hash 桶中的元素数量超过特定的值(默认为 8)便会由链表切换到平衡树,这会将 get()方法的性能从 O(n)提高到 O(logn)。)
11、HashMap 和 Hashtable
同:两者都是用 key-value 方式获取数
据。异:
• 1.null 值:HashMap 允许 null 值作为 key 和 value;Hashtable 不允许 null 的键值;
• 2.顺序性:HashMap 不保证映射的顺序不变,但是作为 HashMap 的子类 LinkedHashMap 默认按照插入顺序来进行映射的顺序;Hashtable 无法保证;
• 3.线程安全:HashMap 是非同步的(非线程安全),效率高;Hashtable 是同步的(线程安全的),效率低。(HashMap 同步通过 Collections.synchronizedMap()实现)
• 4.快速失败机制:迭代 HashMap 采用 fail-fast 快速失败机制(快速失败机制:是一个线程或软件对于其故障做出的响应,用来即时报告可能会导致失败的任何故障情况,如果一个
Iterator 在集合对象上创建了,其他线程想结构化的修改该集合对象,抛出并发修改异常 ConcurrentModificationException);而 HashTable 的 enumerator 迭代器不是 fail-fast 的
(Hashtable 的上
下文同步:一个时间点只能有一个线程可以修改哈希表,任何线程在执行 Hashtable 的更新操作前需要获取对象锁,其他线程等待锁的释放;
• 5.父类:HashMap 继承 AbstractMap,Hashtable 继承 Dictionary;
• 6.数组默认大小:HashMap 底层数组的默认大小是 16,扩容是 2*old;Hashtable 底层数组默认是 11,扩容方式是 2*old+1;
• 7.效率:HashMap 是非线程安全的,单线程下效率高;Hashtable 是线程安全的,方法都加了 synchronized 关键字进行同步,效率较低;
• 8.计算 hash 方式不同:HashMap 是二次 hash,对 key 的 hashCode 进行二次 hash,获得更好的散列值;而 Hashtable 是直接使用 key 的 hashCode 对 table 数组进行取模。
如何让 HashMap 同步
通过 Collections 集合工具类中的 synchronizedMap()方法实现同步:Map map = Collections.synchronizedMap(hashMap);
Collections.synchronizedMap()实现原理是 Collections 定义了一个 SynchronizedTMBap 的内部类,这个类实现了 Map 接口,在调用方法时使用 synchronized 来保证线程同步,当然了实
际上操作的还是我们传入的 HashMap 实例,简单的说就是 Collections.synchronizedMap()方法帮我们在操作 HashMap 时自动添加了 synchronized 来实现线程同步,类似的其它
Collections.synchronizedXX 方法也是类似原理
12、Collection 和 Collections 的区别
• Collection 是集合类的顶层接口,主要子接口由 List、Set 和 Queue 组成。
• Collections 是针对集合类的工具类,提供操作集合的一系列静态方法,如线程安全化、搜索、排序等操作。
• Collections 的用法:当一个集合被作为参数传递给一个函数时,如何才可以确保函数不能修改它:在作为参数传递之前,我们可以使用 Collections.unmodifiableCollection(Collection
c) 方法创建一个只读集合,这将确保改变集合的任何操作都会抛出 UnsupportedOperationException。
13、ArrayList 和 LinkedList 的区别?
1. 底层实现:ArrayList 实现是基于动态数组的数据结构,LinkedList 是基于链表的数据结构(双向链表);
2. 查询:对于随机访问 get 和 set,ArrayList 支持,LinkedList 不支持,因为 LinkedList 要移动指针;
3. 增删:对于新增和删除操作 add 和 remove,在 ArrayList 的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在 LinkedList 的中间插入或删除一个元素的开销是
固定的。
4. 应用场景:ArrayList 适合一列数据的后面添加数据而不是在前面或中间,且需要随机访问元素;LinkedList 适合在一列数据的前面或中间添加或删除数据,且按照顺序访问其中的元
素。
5. 消耗内存:LinkedList 比 ArrayList 消耗更多的内存,因为 LinkedList 中的每个节点都存储前后节点的引用。(双向链表) 14、ArrayList 和 Vector 的区别?
1.线程安全性:ArrayList 是非线程安全的,Vector 是线程安全的,如果需要在迭代的时候对列表进行改变,使用 CopyOnWriteArrayList。
2.效率:ArrayList 是非同步的,效率高;Vector 是同步的,效率低;
15、Hashmap 和 Hashset 区别
HashSet 底层是通过 HashMap 实现的