1. 程式人生 > >Java HashSet

Java HashSet

clas static 返回 hashmap class 姓名 while code ash

Set集合,先從HashSet學起。

1.HashSet底層實際上是一個HashMap,HashMap底層采用了哈希表數據結構。

2.哈希表又叫做散列表,哈希表底層是一個數組,這個數組中每一個元素是一個單向鏈表,每一個單向鏈表都有一個獨一無二的hash值,代表數組的下標。在某個單向鏈表中的每一節點上的hash值是相等的,hash值實際上是key調用hashCode方法,再通過“hash function”轉換成的值。

3.如何向哈希表中添加元素:

先調用被存儲的key的hashCode方法,經過某個算法得出hash值,如果在這個哈希表中不存在這個hash值,則直接加入元素。如果該hash值已經存在,繼續調用key之間的equals方法,如果equals方法返回false,則將該元素添加,如果equals方法返回true,則放棄添加該元素。

4.HashSet其實是HashMap中的key部分,HashSet有什麽特點,HashMap中的key應該有相同的特點。

5.HashMap和HashSet的初試化容量都是16,默認加載因子是0.75.

結合下面這個程序來看。

import java.util.*;
public class HashSetTest01{
public static void main(String[] args){
//創建Set集合
Set s=new HashSet();
//添加元素
s.add(1);
s.add(1);

s.add(23);
s.add(3);
s.add(10);

Iterator it=s.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}

編譯運行後輸出:

1
3
23
10

上述代碼中,首先創建一個Set集合s,然後用add()方法向其中添加元素,之後使用叠代器對其進行叠代並且輸出其中的元素。從編譯運行輸出的結果我們可以看出,Set集合是無序並且不可重復的。

接下來看看看關於往Set集合中存儲的元素,該元素的hashCode和equals方法。結合以下代碼來看:

import java.util.*;
public class HashSetTest02{
public static void main(String[] args){
//創建Set集合
Set es=new HashSet();
//創建Employee類型的對象
Employee e1=new Employee("1000","JACK");
Employee e2=new Employee("1000","JACK");
Employee e3=new Employee("2000","JSDD");
Employee e4=new Employee("2001","CJS");
Employee e5=new Employee("3000","sdc");
Employee e6=new Employee("3001","mdwkm");
//Set集合中添加元素
es.add(e1);
es.add(e2);
es.add(e3);
es.add(e4);
es.add(e5);
es.add(e6);
//輸出Set集合元素的個數
System.out.println(es.size());
//查看e1,e2的hashCode()方法
System.out.println(e1.hashCode());
System.out.println(e2.hashCode());
}
}
//根據現實的業務邏輯得知,該公司的員工編號是:1000-9999
class Employee{
String no;
String name;
Employee(String no,String name){
this.no=no;
this.name=name;
}
}

編譯運行後輸出:

6
366712642
1829164700

上述代碼中:

1.首先創建一個Set集合es,接著創建六個Employee類型的對象,e1和e2的工號和名字相同,從編譯運行後的結果可以看出,e1和e2都被添加到Set集合當中去了,在現實中出於實際需要的考慮,e2不應該被添加進去,因此必須重寫Object中的hashCode()方法(Object中的方法一般都是讓我們根據現實業務的需要重寫的)。

2.重寫hashCode()方法有固定的技巧,在上面代碼實例中,以員工編號分組重寫hashCode()方法,使其散列均勻分布。

public int hashCode(){
return no.hashCode();
}

3.當hashCode方法返回的值不同時,可以直接往集合中添加元素。當hashCode方法返回的值相同時,需要調用equals()方法,這裏需要我們重寫equals()方法。

public boolean equals(Object o){
if(this==o){
return true;
}
if(o instanceof Employee){
Employee e=(Employee)o;
if(e.no.equals(this.no) && e.name.equals(this.name)){
return true;
}
}
return false;
}

整個的代碼如下所示:

import java.util.*;
public class HashSetTest02{
public static void main(String[] args){
//創建Set集合
Set es=new HashSet();
//創建Employee類型的對象
Employee e1=new Employee("1000","JACK");
Employee e2=new Employee("1000","JACK");
Employee e3=new Employee("2000","JSDD");
Employee e4=new Employee("2001","CJS");
Employee e5=new Employee("3000","sdc");
Employee e6=new Employee("3001","mdwkm");
//Set集合中添加元素
es.add(e1);
es.add(e2);
es.add(e3);
es.add(e4);
es.add(e5);
es.add(e6);
//輸出Set集合元素的個數
System.out.println(es.size());
//查看e1,e2的hashCode()方法
System.out.println(e1.hashCode());
System.out.println(e2.hashCode());
}
}
class Employee{
String no;
String name;
Employee(String no,String name){
this.no=no;
this.name=name;
}
//重寫equals方法
//如果員工編號相同,並且名字相同,則是同一個對象
public boolean equals(Object o){
if(this==o){
return true;
}
if(o instanceof Employee){
Employee e=(Employee)o;
if(e.no.equals(this.no) && e.name.equals(this.name)){
return true;
}
}
return false;
}

//重寫hashCode方法
public int hashCode(){
return no.hashCode();
}
}

重寫hashCode和equals方法之後,編譯運行輸出:

5
1507423
1507423

從上面的結果可以看出,當出現相同的員工編號和姓名時,只會添加進去一個對象,實現了現實業務的需求。

Java HashSet