前言
Hashset是基于HashMap实现的,默认构造函数是构建一个初始容量为16,负载因子为0.75 的HashMap。封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 Object 对象。
HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许key使用null元素(1个)。
代码实现
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成。
1)MySet接口
package com.cxx.list.hashset;
import java.util.Iterator;
/**
* @Author: cxx
* Myset接口 - 简单写上几个方法
* @Date: 2018/6/8 9:37
*/
public interface MySet<E> {
//添加元素
boolean add(E e);
//移除元素
boolean remove(E e);
//是否含有元素
boolean contains(Object o);
//set大小
int size();
//是否为空
boolean isEmpty();
//迭代
Iterator<E> iterator();
}
2)MyHashSet实现类
package com.cxx.list.hashset;
import com.cxx.common.NULL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
/**
* @Author: cxx
* MyHashSet实现类
* HashSet底层的数据存取是通过HashMap实现的
* HashSet大部分的方法都是直接调用HashMap的方法就可以实现的
* @Date: 2018/6/8 9:39
*/
public class MyHashSet<E> implements MySet<E> {
private HashMap<E,Object> map;
//定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
static final Object PRECENT = new Object();
//构造函数
public MyHashSet(){
//底层会初始化一个空的HashMap,并使用默认初始容量为16和加载因子0.75。
map = new HashMap<>();
}
/**
* @param initialCapacity 初始容量。
*/
public MyHashSet(int initialCapacity){
this.map = new HashMap<>(initialCapacity);
}
/**
* @param initialCapacity 初始容量。
* @param inithialLoadFactor 加载因子
*/
public MyHashSet(int initialCapacity,float inithialLoadFactor){
this.map = new HashMap<>(initialCapacity,inithialLoadFactor);
}
@Override
public boolean add(E e) {
//集合中原有Entry的key相同(hashCode()返回值相等,通过equals比较也返回true)
//HashMap的put的key相同,那么value会被新的取代,这也说明HashSet不允许有重复的元素
return map.put(e,PRECENT)== null;
}
@Override
public boolean remove(E e) {
return map.remove(e)==PRECENT;
}
@Override
public boolean contains(Object o) {
return map.containsKey(o);
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public Iterator<E> iterator() {
return map.keySet().iterator();
}
}
3)MySetTest测试类
package com.cxx.list.hashset;
import java.util.Iterator;
/**
* @Author: cxx
* 自定义HashSet-测试
* @Date: 2018/6/8 9:57
*/
public class MySetTest {
public static void main(String[] args) {
MySet mySet= new MyHashSet();
mySet.add(1);
mySet.add(2);
mySet.add(5);
mySet.add(null);
System.out.println("size:"+mySet.size());
Iterator iterator = mySet.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
System.out.println();
System.out.println("插入重复元素:2");
mySet.add(2);
mySet.add(null);
Iterator iterator1 = mySet.iterator();
while (iterator1.hasNext()){
System.out.print(iterator1.next()+" ");
}
}
}