我们在工作中时常会用到HashSet
,面试也有时候容易被问到,下面咱们就来聊聊HashSet
。
使用案例
public class Test {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("Java");
hashSet.add("R");
hashSet.add("C");
hashSet.add("C#");
hashSet.add("C#");
hashSet.add("Java");
hashSet.add(null);
System.out.println("hashSet的长度:" + hashSet.size());
//第一种遍历方式
System.out.println("第一种方式遍历");
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next());
System.out.print(" ");
}
System.out.println("");
System.out.println("第二种方式遍历");
for (String string : hashSet) {
System.out.print(string);
System.out.print(" ");
}
}
}
输出
hashSet的长度:5
第一种方式遍历
C# null Java R C
第二种方式遍历
C# null Java R C
从上面的例子可以得知几个结果:
1,不能放入重复的。
2,不是按照放入的顺序存放的。
3,null也可以存放。
关键源码
HashSet
的类图
我们来看看HashSet
到底是怎么玩的
从JDK1.2
开始有的HashSet
,实现了解耦Set,Cloneable
,Serializable
。
- Set是个接口,定义了很多方法。
Cloneable
可以对象克隆。Serializable
可以序列化与反序列。- 继承了抽象类
AbstractSet
AbstractSet
也是Set接口的实现类,主要有以下几个方法:
AbstractSet
实现了三个方法equals
、hashCode
、removeAll
。然后所有继承AbstractSet
的子类都不用自己去实现此三个方法。
Set
定义了如下方法:
HashSet
中关键的变量和方法:
//定义了一个HashMap类型的变量
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
//与备份Map中的对象关联的虚拟值
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
//设置HashSet的容量其实就是设置HashMap的容量
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
//求HashSet的大小就是求HashMap
public int size() {
return map.size();
}
//往HashSet存放数据其实就是往HashMap存放数据
//数据作为key,然后value就是固定Object对象PRESENT
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
....
//序列化与反序列化
private void writeObject(java.io.ObjectOutputStream s){
//...
}
private void readObject(java.io.ObjectInputStream s){
//...
}
可以看出,HashSet
的操作都是基于HashMap
的操作。
总结
HashSet
的所有操作都是基于HashMap
进行操作,用存放进HashSet
的数据作为HashMap
的key在使用一个固定Object对象作为HashMap
的value。
在这金三银四的季节,栈长为大家准备了四份面试宝典:
《java面试宝典5.0》
《Java(BAT)面试必备》
《350道Java面试题:整理自100+公司》
《资深java面试宝典-视频版》
大量电子书籍
分别适用于初中级,中高级,以及资深级工程师的面试复习。
内容包含java基础、javaweb、各个性能优化、JVM、锁、高并发、反射、Spring原理、微服务、Zookeeper、数据库、数据结构、限流熔断降级等等。