1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-20 22:17:09 +08:00

Merge pull request #1393 from Aaron-Ge/master

修改文本内容
This commit is contained in:
Guide哥 2021-09-13 22:37:39 +08:00 committed by GitHub
commit 87d31f1b3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -376,9 +376,9 @@ Output
### 1.5.1. HashMap 和 Hashtable 的区别
1. **线程是否安全:** `HashMap` 是非线程安全的,`HashTable` 是线程安全的,因为 `HashTable` 内部的方法基本都经过`synchronized` 修饰。(如果你要保证线程安全的话就使用 `ConcurrentHashMap` 吧!);
2. **效率:** 因为线程安全的问题,`HashMap` 要比 `HashTable` 效率高一点。另外,`HashTable` 基本被淘汰,不要在代码中使用它;
3. **对 Null key 和 Null value 的支持:** `HashMap` 可以存储 null 的 key 和 value但 null 作为键只能有一个null 作为值可以有多个HashTable 不允许有 null 键和 null 值,否则会抛出 `NullPointerException`
1. **线程是否安全:** `HashMap` 是非线程安全的,`Hashtable` 是线程安全的,因为 `Hashtable` 内部的方法基本都经过`synchronized` 修饰。(如果你要保证线程安全的话就使用 `ConcurrentHashMap` 吧!);
2. **效率:** 因为线程安全的问题,`HashMap` 要比 `Hashtable` 效率高一点。另外,`Hashtable` 基本被淘汰,不要在代码中使用它;
3. **对 Null key 和 Null value 的支持:** `HashMap` 可以存储 null 的 key 和 value但 null 作为键只能有一个null 作为值可以有多个Hashtable 不允许有 null 键和 null 值,否则会抛出 `NullPointerException`
4. **初始容量大小和每次扩充容量大小的不同 ** ① 创建时如果不指定容量初始值,`Hashtable` 默认的初始大小为 11之后每次扩充容量变为原来的 2n+1。`HashMap` 默认的初始化大小为 16。之后每次扩充容量变为原来的 2 倍。② 创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小,而 `HashMap` 会将其扩充为 2 的幂次方大小(`HashMap` 中的`tableSizeFor()`方法保证,下面给出了源代码)。也就是说 `HashMap` 总是使用 2 的幂作为哈希表的大小,后面会介绍到为什么是 2 的幂次方。
5. **底层数据结构:** JDK1.8 以后的 `HashMap` 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8将链表转换成红黑树前会判断如果当前数组的长度小于 64那么会选择先进行数组扩容而不是转换为红黑树将链表转化为红黑树以减少搜索时间。Hashtable 没有这样的机制。
@ -438,7 +438,7 @@ Output
实现 `NavigableMap` 接口让 `TreeMap` 有了对集合内元素的搜索的能力。
实现`SortMap`接口让 `TreeMap` 有了对集合中的元素根据键排序的能力。默认是按 key 的升序排序,不过我们也可以指定排序的比较器。示例代码如下:
实现`SortedMap`接口让 `TreeMap` 有了对集合中的元素根据键排序的能力。默认是按 key 的升序排序,不过我们也可以指定排序的比较器。示例代码如下:
```java
/**
@ -617,9 +617,9 @@ static int hash(int h) {
**两者的对比图:**
**HashTable:**
**Hashtable:**
![HashTable全表锁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HashTable全表锁.png)
![Hashtable全表锁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-6/HashTable全表锁.png)
<p style="text-align:right;font-size:13px;color:gray">https://www.cnblogs.com/chengxiao/p/6842045.html></p>
@ -633,7 +633,7 @@ static int hash(int h) {
![Java8 ConcurrentHashMap 存储结构(图片来自 javadoop](./images/java8_concurrenthashmap.png)
JDK1.8 的 `ConcurrentHashMap`**Segment 数组 + HashEntry 数组 + 链表**,而是 **Node 数组 + 链表 / 红黑树**。不过Node 只能用于链表的情况,红黑树的情况需要使用 **`TreeNode`**。当冲突链表达到一定长度时,链表会转换成红黑树。
JDK1.8 的 `ConcurrentHashMap`**Segment 数组 + HashEntry 数组 + 链表**,而是 **Node 数组 + 链表 / 红黑树**。不过Node 只能用于链表的情况,红黑树的情况需要使用 **`TreeNode`**。当冲突链表达到一定长度时,链表会转换成红黑树。
### 1.5.10. ConcurrentHashMap 线程安全的具体实现方式/底层具体实现