自己实现HashSet-通俗易懂

前言

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()+" ");
        }
    }
}

效果截图

这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_37499059/article/details/80619167
今日推荐