您的位置:首页 > 编程语言 > Java开发

【Java集合系列四】HashSet和LinkedHashSet解析

2017-07-29 17:55 351 查看
2017-07-29 16:58:13

一、简介

1、Set概念

Set可以理解为集合,非常类似数据概念中的集合,集合三大特征:1、确定性;2、互异性;3、无序性,因此Set实现类也有类似的特征。

2、HashSet

HashSet继承自AbstractSet,实现了Set接口,但是其源码非常少,也非常简单。内部使用HashMap来存储数据,数据存储在HashMap的key中,value都是同一个默认值:

1 public class MainSet {
2     public static void main(String[] args) {
3         Object value = new Object();
4         HashMap<String, Object> hashMap = new HashMap<>();
5         HashSet<String> hashSet = new HashSet<>();
6         LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>();
7         LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
8         hashSet.add("java");
9         hashMap.put("java", value);
10         linkedHashSet.add("java");
11         linkedHashMap.put("java", value);
12
13         hashSet.add("golang");
14         hashMap.put("golang", value);
15         linkedHashSet.add("golang");
16         linkedHashMap.put("golang", value);
17
18         hashSet.add("python");
19         hashMap.put("python", value);
20         linkedHashSet.add("python");
21         linkedHashMap.put("python", value);
22
23         hashSet.add("ruby");
24         hashMap.put("ruby", value);
25         linkedHashSet.add("ruby");
26         linkedHashMap.put("ruby", value);
27
28         hashSet.add("scala");
29         hashMap.put("scala", value);
30         linkedHashSet.add("scala");
31         linkedHashMap.put("scala", value);
32
33         hashSet.add("c");
34         hashMap.put("c", value);
35         linkedHashSet.add("c");
36         linkedHashMap.put("c", value);
37
38         System.out.println("默认插入序:\njava\tgolang\tpython\truby\tscala\tc");
39
40         System.out.println(" \nHashSet:-------------------");
41         for (String str : hashSet) {
42             System.out.print(str + "\t");
43         }
44
45         System.out.println(" \n\nHashMap:-------------------");
46         for (Map.Entry<String, Object> entry : hashMap.entrySet()) {
47             System.out.print(entry.getKey() + "\t");
48         }
49
50         System.out.println(" \n\nLinkedHashSet:-------------------");
51         for (String str : linkedHashSet) {
52             System.out.print(str + "\t");
53         }
54
55         System.out.println(" \n\nLinkedHashMap:-------------------");
56         for (Map.Entry<String, Object> entry : linkedHashMap.entrySet()) {
57             System.out.print(entry.getKey() + "\t");
58         }
59     }
60 }


View Code

3、debug中奇异现象



如上,我们明明添加了6个元素,但是table中只有5个,怎么回事呢?初步猜测应该是“c”元素和其中某一个元素位于同一个bucket,验证如下:



我们发现,“java”竟然和“c”位于同一个bucket,他俩在同一个链表中。唯一的疑惑是:“c”是后加入的元素,按理说应该在链表的表头才对啊,这个问题还需要探究。

同时这里也介绍了一种能debug到HashMap内部数据结构的方法,但是需要注意2个问题:

1、需要在AS中设置一下,否则debug看到的信息不是这样的,如下图:



2、直接使用table[3].next是不行的, 需要像图上那样,些完整的包名才行。

4、继续debug

如上所示,设置HashSet之后,同样能看到如下信息:



看看LinkedHashMap,如下图,LinkedHashMap中多了head和tail,这是指向表头、表尾的指针,head指向“java”,tail指向“c”,这和我们的插入序保持一致,但是实际存储和之前是一样的。



LinkedHashSet如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: