程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JAVA提高教程(2)-認識Set集合之HashSet

JAVA提高教程(2)-認識Set集合之HashSet

編輯:關於JAVA

集合在Java裡面的作用非凡,我們常用的有Set,List和Map三種,我們先熟悉一下Set ,特別是HashSet的使用

package collection.lession2;

import java.util.HashSet;
import java.util.Set;

/**
* 老紫竹JAVA提高教程(2)-認識Set集合之HashSet。<br>
* Set用來保存不允許重復的數據。可以是任何對象類型。<br>
* JDK5以後,主類型可以通過autobox 放入Set裡面。
* 
* @author 老紫竹 JAVA世紀網(java2000.net)
* 
*/
public class Lession2 {

  public static void main(String[] args) {
   // 普通測試
   testNormal();

   // 測試HashSet的特殊性
   testForHashSet();
   testForHashSet2();
  }

  /**
  * 測試保存混合類型的數據.
  */
  public static void testNormal() {
   System.out.println("----- testNormal -----------");
   // Set有多個實現,我們先看看最常用的HashSet
   Set set = new HashSet();
   // 添加一個字符串
   set.add("字符串");
   // 添加一個整數對象
   set.add(new Integer(1));
   // 利用JDK5的特性,增加一個浮點數
   set.add(123.45);

   // 我們看看集合裡對象的數量
   System.out.println(set.size());

   // 我們嘗試增加一個重復的字符串
   set.add("字符串");

   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());

   // 我們來測試看看是否集合裡包含了某個數據
   System.out.println(set.contains(123.45));

   // 我們從裡面把這個浮點數刪除
   set.remove(123.45);

   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());
  }

  /**
  * 專門針對HashSet的測試。
  */
  public static void testForHashSet() {
   System.out.println("----- testForHashSet -----------");
   HashSet<MyObject> set = new HashSet<MyObject>();

   // 增加一個null對象
   set.add(null);
   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());
   // 再次增加一個null看看
   set.add(null);
   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());

   MyObject obj = new MyObject("java2000", 2);
   set.add(obj);

   obj = new MyObject("csdn", 10);
   set.add(obj);

   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());

   // 判斷是否包含某個對象
   System.out.println(set.contains(obj));

   obj = new MyObject("java2000_net", 2);
   set.add(obj);

   // 我們再次看看集合裡對象的數量
   System.out.println(set.size());

   // 我們嘗試把obj再次放入set看看
   // 並沒有增加,因為是重復的
   set.add(obj);
   System.out.println(set.size());

   // 我們構造一個新的對象,內容和前面的相同
   obj = new MyObject("java2000_net", 2);
   set.add(obj);
   System.out.println(set.size());

   // 我們修改一下obj裡面的年齡,再看看
   obj.setAge(3);

   // 我們再測試看看是否包含此對象。
   // 請注意,我們這個obj和前面的obj是同一個對象
   // 我們僅僅修改了一下我們的年齡
   System.out.println(set.contains(obj));

   // 我們嘗試把obj再次放入set看看
   // 我們又增加了長度
   set.add(obj);
   System.out.println(set.size());
  }

  /**
  * 專門針對HashSet的測試2。
  */
  public static void testForHashSet2() {
   System.out.println("----- testForHashSet2 -----------");
   HashSet<MyObject2> set = new HashSet<MyObject2>();
   MyObject2 obj = null;
   for (int i = 0; i < 3; i++) {
    obj = new MyObject2("java2000" + i, i);
    set.add(obj);
    System.out.println(set.size());
   }
  }

}

class MyObject {
  private int age;
  private String name;

  public int getAge() {
   return age;
  }

  public void setAge(int age) {
   this.age = age;
  }

  public String getName() {
   return name;
  }

  public void setName(String name) {
   this.name = name;
  }

  MyObject(String name, int age) {
   this.name = name;
   this.age = age;
  }

  public boolean equals(Object obj) {
   System.out.println("equals");
   if (obj == null || !(obj instanceof MyObject)) {
    return false;
   }
   MyObject o = (MyObject) obj;
   return this.age == o.age && this.name.equals(o.name);
  }

  public int hashCode() {
   int hashCode = name.hashCode() + String.valueOf(age).hashCode();
   return hashCode;
  }
}

class MyObject2 {
  private int age;
  private String name;

  public int getAge() {
   return age;
  }

  public void setAge(int age) {
   this.age = age;
  }

  public String getName() {
   return name;
  }

  public void setName(String name) {
   this.name = name;
  }

  MyObject2(String name, int age) {
   this.name = name;
   this.age = age;
  }

  public boolean equals(Object obj) {
   System.out.println("equals");
   if (obj == null || !(obj instanceof MyObject2)) {
    return false;
   }
   MyObject2 o = (MyObject2) obj;
   return this.age == o.age && this.name.equals(o.name);
  }

  public int hashCode() {
   return 1;
  }
}

class MyObject3 {
  private int age;
  private String name;

  // 采用一個變量進行控制
  // 一旦生成了hashCode,則不再變動
  private int HASHCODE = Integer.MIN_VALUE;

  public int hashCode() {
   if (HASHCODE == Integer.MIN_VALUE) {
    // 重新生成本類的hashCode
    HASHCODE = name.hashCode() + String.valueOf(age).hashCode();

   }
   return HASHCODE;
  }
}

說明,針對HashSet:

Set不允許重復

允許 null,重復的null只算一個

判斷是否存在一個數據(是否重復),先判斷其hashCode是否存在,若存在再逐個判斷 hashCode相同的數據是否相等

判斷是否相等,除了hashCode相等外,還要判斷對象引用相等(==),或者 equals

如果一個對象的hashCode變動了,會造成找不到這個對象,也就出現了內存洩漏的危 險。

hashCode 方法是HashSet裡面對象的關鍵,它的算法影響到了數據的分散和查找效率 。某個確認對象的hashCode不應該變動,避免出現內存洩漏,可以采用如下方法,來方式 屬性變化造成hashCode變化

class MyObject3 {
  private int age;
  private String name;

  // 采用一個變量進行控制
  // 一旦生成了hashCode,則不再變動
  private int HASHCODE = Integer.MIN_VALUE;

  public int hashCode() {
   if (HASHCODE == Integer.MIN_VALUE) {
    // 重新生成本類的hashCode
    HASHCODE = name.hashCode() + String.valueOf(age).hashCode();

   }
   return HASHCODE;
  }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved