簡介
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() / 0.75F) + 1, 16));
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()這兩個方法。