Skip to content

Commit

Permalink
correct some typo
Browse files Browse the repository at this point in the history
  • Loading branch information
CarpenterLee committed May 28, 2016
1 parent 0556912 commit 8b8991d
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions markdown/6-HashSet and HashMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
# 总体介绍
之所以把*HashSet**HashMap*放在一起讲解,是因为二者在Java里有着相同的实现,前者仅仅是对后者做了一层包装,也就是说***HashSet*里面有一个*HashMap*(适配器模式)**。因此本文将重点分析*HashMap*

*HashMap*实现了*Map*接口,允许放入`null`元素,除该类未实现同步外,其余跟`Hashtable`大致相同*TreeMap*不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个*HashMap*的顺序可能会不同。
*HashMap*实现了*Map*接口,即允许放入`key``null`的元素,也允许插入`value``null`的元素;除该类未实现同步外,其余跟`Hashtable`大致相同*TreeMap*不同,该容器不保证元素顺序,根据需要该容器可能会对元素重新哈希,元素的顺序也会被重新打散,因此不同时间迭代同一个*HashMap*的顺序可能会不同。
根据对冲突的处理方式不同,哈希表有两种实现方式,一种开放地址方式(Open addressing),另一种是冲突链表方式(Separate chaining with linked lists)。**Java *HashMap*采用的是冲突链表方式**
![HashMap_base](../PNGFigures/HashMap_base.png)

从上图容易看出,如果选择合适的哈希函数,`put()``get()`方法可以在常数时间内完成。但在对*HashMap*进行迭代时,需要遍历整个table以及后面跟的冲突链表。因此对于迭代比较频繁的场景,不宜将*HashMap*的初始大小设的过大。

有两个参数可以影响*HashMap*的性能:初始容量(inital capacity)和负载系数(load factor)。初始容量指定了初始`table`的大小,负载系数用来指定自动扩容的临界值。当`entry`的数量超过`capacity*load_factor`时,容器将自动扩容并重新哈希。对于插入元素较多的场景,将初始容量设大可以减少重新哈希的次数。

将对向放入到*HashMap**HashSet*中时,有两个方法需要特别关心:`hashCode()``equals()`**`hashCode()`方法决定了对象会被放到哪个`bucket`里,当多个对象的哈希值冲突时,`equals()`方法决定了这些对象是否是“同一个对象”**。所以,如果要将自定义的对象放入到`HashMap``HashSet`中,需要*@Override*`hashCode()``equals()`方法。
将对象放入到*HashMap**HashSet*中时,有两个方法需要特别关心:`hashCode()``equals()`**`hashCode()`方法决定了对象会被放到哪个`bucket`里,当多个对象的哈希值冲突时,`equals()`方法决定了这些对象是否是“同一个对象”**。所以,如果要将自定义的对象放入到`HashMap``HashSet`中,需要*@Override*`hashCode()``equals()`方法。

# 方法剖析

Expand Down Expand Up @@ -59,7 +59,7 @@ void addEntry(int hash, K key, V value, int bucketIndex) {

## remove()

`remove(Object key)`的作用是删除`key`值对应的`entry`,该方法的具体逻辑是在`removeEntryForKey(Object key)`里实现的。`removeEntryForKey()`方法会首先找到`key`值对应的`entry`,然后删除该`entry`修改链表的相应指针)。查找过程跟`getEntry()`过程类似。
`remove(Object key)`的作用是删除`key`值对应的`entry`,该方法的具体逻辑是在`removeEntryForKey(Object key)`里实现的。`removeEntryForKey()`方法会首先找到`key`值对应的`entry`,然后删除该`entry`修改链表的相应引用)。查找过程跟`getEntry()`过程类似。
![HashMap_removeEntryForKey](../PNGFigures/HashMap_removeEntryForKey.png)
```Java
//removeEntryForKey()
Expand Down

0 comments on commit 8b8991d

Please sign in to comment.