Skip to content

Commit b64dffb

Browse files
authored
Merge pull request crossoverJie#10 from crossoverJie/fix
HashSet
2 parents 235628e + ab14416 commit b64dffb

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

MD/collection/HashSet.md

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# HashSet 底层分析
2+
3+
`HashSet` 是一个不允许存储重复元素的集合,它的实现比较简单,只要理解了 `HashMap``HashSet` 就水到渠成了。
4+
5+
## 成员变量
6+
首先了解下 `HashSet` 的成员变量:
7+
8+
```java
9+
private transient HashMap<E,Object> map;
10+
11+
// Dummy value to associate with an Object in the backing Map
12+
private static final Object PRESENT = new Object();
13+
```
14+
15+
发现主要就两个变量:
16+
17+
- `map` :用于存放最终数据的。
18+
- `PRESENT` :是所有写入 map 的 `value` 值。
19+
20+
## 构造函数
21+
22+
```
23+
public HashSet() {
24+
map = new HashMap<>();
25+
}
26+
27+
public HashSet(int initialCapacity, float loadFactor) {
28+
map = new HashMap<>(initialCapacity, loadFactor);
29+
}
30+
```
31+
构造函数很简单,利用了 `HashMap` 初始化了 `map`
32+
33+
## add
34+
35+
```java
36+
public boolean add(E e) {
37+
return map.put(e, PRESENT)==null;
38+
}
39+
```
40+
41+
比较关键的就是这个 `add()` 方法。
42+
可以看出它是将存放的对象当做了 `HashMap` 的健,`value` 都是相同的 `PRESENT` 。由于 `HashMap``key` 是不能重复的,所以每当有重复的值写入到 `HashSet` 时,`value` 会被覆盖,但 `key` 不会收到影响,这样就保证了 `HashSet` 中只能存放不重复的元素。
43+
44+
## 总结
45+
46+
`HashSet` 的原理比较简单,几乎全部借助于 `HashMap` 来实现的。
47+
48+
所以 `HashMap` 会出现的问题 `HashSet` 依然不能避免。
49+

src/main/java/com/crossoverjie/actual/AbstractMap.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public AbstractMap() {
8585
}
8686

8787
/**
88-
* 开启一个线程检查最先放入队列的值是否超期
88+
* 开启一个线程检查最先放入队列的值是否超期 设置为守护线程
8989
*/
9090
private void executeCheckTime() {
9191
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()

src/main/java/com/crossoverjie/basic/StringTest.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,29 @@
1111
*/
1212
public class StringTest {
1313

14-
public static void main(String[] args) throws NoSuchFieldException {
14+
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
1515
String a = "123";
16+
//这里的 a 和 b 都是同一个对象,指向同一个字符串常量池对象。
17+
String b = "123" ;
18+
String c = new String("123") ;
19+
20+
System.out.println("a=b:" + (a == b));
21+
System.out.println("a=c:" + (a == c));
22+
1623
System.out.println("a=" + a);
1724

1825
a = "456";
1926
System.out.println("a=" + a);
2027

21-
Field value = a.getClass().getField("value");
28+
29+
//用反射的方式改变字符串的值
30+
Field value = a.getClass().getDeclaredField("value");
31+
//改变 value 的访问属性
32+
value.setAccessible(true) ;
33+
34+
char[] values = (char[]) value.get(a);
35+
values[0] = '9' ;
36+
37+
System.out.println(a);
2238
}
2339
}

src/main/java/com/crossoverjie/concurrent/Singleton.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.crossoverjie.concurrent;
22

33
/**
4-
* Function:
4+
* Function:单例模式-双重检查锁
55
*
66
* @author crossoverJie
77
* Date: 09/03/2018 01:14

0 commit comments

Comments
 (0)