天天看点

HashSet 详解

简介

HashSet使我们平时比较常用的一个集合类,实现的是Collection下面的Set接口,具有如下特点:

1、线程不安全

2、无序(不会保证其中元素的顺序会与加入时一样)

3、存放元素不可重复(具体看本文最后一节)

4、HashSet是基于HashMap实现的

HashSet的实现

接下来我们来看一看HashSet的一些常用到的内容。

1、全局变量

private transient HashMap map;
private static final Object PRESENT = new Object();
           

HashSet的内容就是存放于map中的

重点内容

//无参构造方法,初始化map
public HashSet(){
    map = new HashMap();
}
           
//带Collection参数的构造方法,初始化map,并指定长度,同时执行addall方法
public HashSet(Collection collection){
    map = new HashMap(Math.max((int)((float)collection.size() / F) + , ));
    addAll(collection);
}
           
//就是获取map的size
public int size(){
    return map.size();
}

//map是否为空
public boolean isEmpty(){
    return map.isEmpty();
}

//把元素当作key放入到map中
public boolean add(Object obj){
    return map.put(obj, PRESENT) == null;
}

//map的key是否包含该元素
public boolean contains(Object obj){
    return map.containsKey(obj);
}

public boolean remove(Object obj){
    return map.remove(obj) == PRESENT;
}

public void clear(){
    map.clear();
}

//removeall的实现,调用的是父类AbstractSet的removeAll方法
 public boolean removeAll(Collection collection){
    boolean flag = false;
    if(size() > collection.size()){
        for(Iterator iterator = collection.iterator(); iterator.hasNext();)
            flag |= remove(iterator.next());
    } else{
        Iterator iterator1 = iterator();
        do{
            if(!iterator1.hasNext())
                break;
            if(collection.contains(iterator1.next())){
                iterator1.remove();
                flag = true;
            }
        } while(true);
    }
    return flag;
}
           

由此我们可以看出,HashSet的内部原理就是把元素放入到里面的一个HashMap的key中,其它的基本就是调用的HashMap和父类的方法。

HashSet中是如何判断元素是否重复的

HashSet不能添加重复的元素,当调用add(Object)方法时候,

首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素;

如果已存在则调用Object对象的equals方法判断是否返回true,如果为true则说明元素已经存在,如为false则插入元素。

关于java中hashcode和equal我们可以参照下面这篇博文 java hashcode和equal总结

Object类的HashCode方法其实返回的就是对象的地址

注意:为了保证HashSet中的对象不会出现重复值,在被存放元素的类中必须要重写hashCode()和equals()这两个方法。