Java HashSet(轉javaeye)

繼承於Set接口,java

一、HashSet不能重複存儲equals相同的數據 。緣由就是equals相同,數據的散列碼也就相同(hashCode必須和equals兼容)。大量相同的數據將存放在同一個散列單元所指向的鏈表中,形成嚴重的散列衝突,對查找效率是災難性的。算法

      二、HashSet的存儲是無序的 ,沒有先後關係,他並非線性結構的集合。this

      三、hashCode必須和equals必須兼容, 這也是爲了第1點。spa

 

1. 繼承結構
java.lang.Object
   |_ java.util.AbstractCollection<E>
        |_ java.util.AbstractSet<E>
              |_ java.util.HashSet<E>

2. 主要方法
    add(Object)
    addAll(Collection)
    remove(object)
    removeAll(Collection)
    size()
    iterator()
    toArray()
    clear()
    isEmpty()
    contain(object)
    containAll(Collection)

3. 不容許出現相同的項
   Set集合中不容許出現相同的項,Set集合在用Add()方法添加一個新項時,首先會調用equals(Object o)來比較新項和已有的某項是否相等,而不是用==來判斷相等性,因此對於字符串等已重寫equals方法的類,是按值來比較相等性的
   code

  1. Set<String> setA=(Set<String>)new HashSet();    
  2.   
  3.  setA.add(new String("ABC"));   
  4.  setA.add(new String("CC"));   
  5.  setA.add(new String("ABC"));   
  6.  setA.add(new String("BB"));   
  7.  setA.add(new String("ABC"));   
  8.   
  9.  System.out.println("size="+setA.size()); //3, 相同的項不存儲   
  10.      
  11.  Iterator<String> ite=setA.iterator();   
  12.      
  13.  while(ite.hasNext()){   
  14. stem.out.println(ite.next());//CC BB ABC   
  15.   
  16.  }   
Set<String> setA=(Set<String>)new HashSet(); 
		
    setA.add(new String("ABC"));
    setA.add(new String("CC"));
    setA.add(new String("ABC"));
    setA.add(new String("BB"));
    setA.add(new String("ABC"));

    System.out.println("size="+setA.size()); //3, 相同的項不存儲
	    
    Iterator<String> ite=setA.iterator();
	    
    while(ite.hasNext()){
	System.out.println(ite.next());//CC BB ABC

    }


4. 哈希算法
   在set類型的集合中,如何判斷元素是否重複呢,這就須要使用Object.equals方法,但若是元素不少了,添加一個新元素時,比較的次數 就不少,例如已經有100個元素了,添加第101個元素時,就要和前面的元素比較100次,效率很低。

   JAVA中採用哈希表的原理,哈希是我的名,它提出了哈希算法的概念,哈希算法也稱爲散列算法,是將數據依據酸法直接指定到一個地址上,

   hascode其實是返回的對象存儲的物理地址

   HashSet類按照哈希算法來存取對象,當向集合中加入一個新對象時,會調用對象的HashCode()方法獲得對象的哈希碼,而後根據這個碼計算出對象在集合中存儲的位置。

   Object類中定義了hashCode()和equals(Object o)方法,若是object1.equals(object2),那麼說明這兩個引用變量指向同一個對象,那麼object1 and object2的hashCode也必定相等

   爲了保證HashSet能正常工做,要求當兩個對象用equals比較相等時,hashCode也要相等,不然就會有可能加入兩個相同的項。
   對象

  1.   public class Person {   
  2. private String name;   
  3. private Integer age;   
  4. public Integer getAge() {   
  5.    return age;   
  6. }   
  7. public void setAge(Integer age) {   
  8.    this.age = age;   
  9. }   
  10. public String getName() {   
  11.    return name;   
  12. }   
  13. public void setName(String name) {   
  14.    this.name = name;   
  15. }   
  16.         public boolean equals(Object o){   
  17.     if(this==o)return true;   
  18.        
  19.     if(!(o instanceof Person))   
  20.     return false;   
  21.        
  22.     final Person p=(Person)o;   
  23.     if(this.name.equals(p.getName()))   
  24.     return true;   
  25.     else  
  26.     return false;   
  27.        
  28. }   
  29.  }   
  30.   
  31.  Set<Person> setA=(Set<Person>)new HashSet();      
  32.  Person A=new Person();   
  33.  A.setAge(24);   
  34.  A.setName("Jack");   
  35.        
  36.        
  37.  Person B=new Person();   
  38.  B.setAge(24);   
  39.  B.setName("Jack");   
  40.        
  41.  setA.add(A);   
  42.  setA.add(B);   
  43.  System.out.println("size="+setA.size());  //2     
  44.   
  45.    
public class Person {
	private String name;
	private Integer age;
	public Integer getAge() {
	   return age;
	}
	public void setAge(Integer age) {
	   this.age = age;
	}
	public String getName() {
	   return name;
	}
	public void setName(String name) {
	   this.name = name;
	}
         public boolean equals(Object o){
  	if(this==o)return true;
		
  	if(!(o instanceof Person))
		return false;
		
  	final Person p=(Person)o;
  	if(this.name.equals(p.getName()))
		return true;
  	else
		return false;
		
 }
  }

  Set<Person> setA=(Set<Person>)new HashSet();	
  Person A=new Person();
  A.setAge(24);
  A.setName("Jack");
		
		
  Person B=new Person();
  B.setAge(24);
  B.setName("Jack");
		
  setA.add(A);
  setA.add(B);
  System.out.println("size="+setA.size());  //2


雖然A與B用equals比較相等,但由於HashCode不一樣,HashSet爲A和B計算出了不一樣的存儲位置,因而把他們放到了集合的不一樣位置

能夠重寫hascode和equas方法

  例如:
  繼承

  1. public int hasCode(){   
  2. int result;   
  3. result=(this.name==null?0:name.hashCode());   
  4. result=37*result+(this.age==null?0:age.hashCode());   
  5. return result;   
相關文章
相關標籤/搜索