简介
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()这两个方法。