- 一、基本介绍
- 1.定义
- 2.特点
- 1)无序
- 2)元素唯一
- 3)遍历方式
- 二、实现类
- 1.HashSet(重点)
- 1)介绍
- 2)add(E)机制
- 3)扩容和树化详解
- 2.LinkedHashSet
- 1)介绍
- 2)详述
set接口是集合类接口collection的子接口,其拥有collection的字段和方法,也有自己的特性。set为单列集合,常用方法与collection一样,如add、remove等方法。其常用实现子类有HashSet、LinkedHashSet。
2.特点 1)无序添加和取出的顺序不一致,没有索引。2)元素唯一
不允许出现重复元素,所以最多包含一个null。3)遍历方式
可以使用迭代器和增强for循环,但不能使用普通for循环 。
代码说明:
public class HashSet_ {
public static void main(String[] args) {
//1.HashSet底层是实现HashMap()
//public HashSet() {
// map = new HashMap<>();
// }
HashSet set = new HashSet();
//2.HashSet只能有一个null
//3.HashSet不保证有序,取决于hash后,再确定索引的值
set.add(null);set.add("rookie");set.add("shy");
set.add("jk");set.add("ning");set.add(null);
Iterator iterator = set.iterator();
System.out.println("set=" + set);
while (iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
}
}
运行结果:
set=[null, jk, shy, ning, rookie] null jk shy ning rookie二、实现类 1.HashSet(重点) 1)介绍
set拥有的特性HashSet都拥有
a.HashSet底层是HashMap(即数组+链表+红黑树)。
b.添加一个元素时,先通过算法得到hash值,再转化为索引值。
c.找到数据存储表table,看这个索引之前是否存放的有数据。
d.如果没有,直接加入。
e.如果有,调用equals比较,如果相同,就放弃添加;如果不相同就添加在最后。
f.在java8中,如果一条链表的元素个数达到8个,而且table(即数据数组)的大小达到64就会进行树化(红黑树)
代码说明(包括源码解读):
public class HashSetSource {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add("java");
hashSet.add("c++");
hashSet.add("java");
System.out.println("hashSet=" + hashSet);
}
}
运行结果:
3)扩容和树化详解
代码示例:
public class HashSetIncrease {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
for(int i = 0;i < 100;i++){
hashSet.add(i+1);
}
}
}
调试验证:
数组元素小于12时:
数组元素超过12时:
代码示例:
public class HashSetIncrease {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
for(int i = 0;i < 100;i++){
hashSet.add(new student());
}
}
}
class student{
@Override
public int hashCode() {
return 77;
}
}
通过调试该代码可验证上诉结论。
2.LinkedHashSet 1)介绍LinkedHashSet是HashSet的子类,与HashSet特征相似,相较于HashSet其不同在于集合中的元素是有序的。2)详述
a. LinkedHashSet底层是实现LinkedHashMap(数组+双向链表)。
b. LinkedHashSet的map都有一个head和tail,分别指向头元素和尾元素。
c.table中的每个元素都有before和after字段,分别指向前一个和后一个元素。
d.数组是HashMap
N
o
d
e
类
型
,
元
素
是
L
i
n
k
e
d
H
a
s
h
M
a
p
Node类型,元素是LinkedHashMap
Node类型,元素是LinkedHashMapEntry类型,后者是前者的子类。
static class Entryextends HashMap.Node { Entry before, after; Entry(int hash, K key, V value, Node next) { super(hash, key, value, next); } }
e.LinkedHashSet add方法的底层与HashSet底层类似。



