咱们在工做中时常会用到HashSet
,面试也有时候容易被问到,下面我们就来聊聊HashSet
。
java
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
从上面的例子能够得知几个结果:app
1,不能放入重复的。ide
2,不是按照放入的顺序存放的。spa
3,null也能够存放。3d
HashSet
的类图code
咱们来看看HashSet
究竟是怎么玩的orm
从JDK1.2
开始有的HashSet
,实现了解耦Set,Cloneable
,Serializable
。对象
Set是个接口,定义了不少方法。blog
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的大小就是求HashMappublic int size() { return map.size();}//往HashSet存放数据其实就是往HashMap存放数据//数据做为key,而后value就是固定Object对象PRESENTpublic 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。