Set是Collection子接口;
Set和Collection基本上一樣,一點除外:
Set無法記住添加的順序,不允許包含重復的元素。
當試圖添加兩個相同元素進Set集合,添加操作失敗,add()方法返回false。
Set判斷兩個對象是否相等用equals,而不是使用==。
也就是說兩個對象equals比較返回true,Set集合是不會接受這個兩個對象的。
常用子類:
HashSet:散列存放
TreeSet:有序存放
hashCode方法對於HashSet的作用
HashSet類是Set接口最常用的實現類,采用hash算法存儲數據,具有良好的存儲和查找功能。
散列存儲:不記錄添加順序;排列順序時,順序有可能發生變化;
線程不安全的,多個線程訪問一個HashSet要使用同步代碼;
HashSet集合元素值允許是null,但是最多只能有一個;//因為Set集合就不可以裝重復的對象!
hash(翻譯為哈希,或散列)算法的功能:
保證通過一個對象快速找到另一個對象;
其算法價值體現在速度,可以保證查詢快速執行;
當從HashSet中訪問元素時,HashSet先計算該元素的hashCode(也就是該對象的hashCode方法返回值),然后直接到該HashCode對應的位置取出該元素;
在這里對象的hashCode就好比是數組里的索引,但是不是索引;
HashSet元素添加
當向HashSet集合中存入一個元素時,HashSet會調用該對象的hashCode()方法來得到該對象的hashCode值,判斷已經存儲在集合中的對象的hashCode值是否與添加的對象的hashCode值一致:若不一致:直接添加進去;若一致,再進行equals方法比較,equals方法如果返回true,表明對象已經添加進去了,就不會再添加新的對象了,否則添加進去;
如果我們重寫了equals方法,也要重寫hashCode方法,反之亦然;。
HashSet集合判斷兩個元素相等的標准是兩個對象通過equals方法比較相等,並且兩個對象的hashCode方法返回值也相等。
如果需要某個類的對象保存到HashSet集合中,覆寫該類的equals()和hashCode()方法,應該盡量保證兩個對象通過equals比較返回true時,他們的hashCode返回也相等。
我的總結:
很重要的一點:理解!往HashSet集合里面存入數據,要先后調用兩個方法:hashCode方法和equals方法!!!
備注:使用eclipse添加這兩個方法。
Eg:
package july7;
//hashset方法和equals方法判斷輸入的對象是否重復!
import java.util.HashSet;
import java.util.Set;
class PersonDemo{
private String name;
public PersonDemo(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "name= " + name ;
}
//沒有覆寫hashcode和equals方法前,顯示三次(一樣的)。覆寫后,只剩下一個了!說明覆寫后方法起作用了,重復的輸入不進去!
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PersonDemo other = (PersonDemo) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class Demo12 {
public static void main(String[] args) {
Set s = new HashSet();
s.add(new PersonDemo("章澤天"));
s.add(new PersonDemo("章澤天"));
s.add(new PersonDemo("章澤天"));
System.out.println(s);
}
}
