Java結合中的HashSet
HashSet是Set介面的典型實現,大多數時候使用Set集合時就是使用這個實現類。HashSet按Hash演算法來儲存集合中的元素,因此具有很好的存取和查詢效能。
HashSet具有以下特點:
(1)不能保證元素的排列順序,順序可能與新增順序不同,順序也可能發生變化。
(2)HashSet不是同步的,如果多個執行緒同時訪問一個HashSet,假設有兩個或者兩個以上執行緒同時修改了HashSet集合時,則必須通過程式碼來保證其同步。
(3)集合元素值可以是null。
當向HashSet集合中存入一個元素時,HashSet會呼叫該物件的hashCode()方法來得到該物件的hashCode值,然後根據該hashCode值決定該物件在HashSet中的儲存位置。如果有兩個元素通過equals()方法比較返回true,但它們的hashCode()方法返回值不相等,HashSet將會把它們儲存在不同的位置,依然可以新增成功。
也就是說,HashSet集合判斷兩個元素相等的標準是兩個物件通過equals()方法比較相等,並且兩個物件的hashCode()方法返回值也相等。
下面程式分別提供了三個類A、B、C,它們分別重寫了equals()、hashCode()、兩個方法的一個或全部,通過此程式可以讓讀者看到HashSet判斷集合元素相同的標準。
package com.zhao.two;
import java.util.HashSet;
class A{
public boolean equals(Object obj){
return true;
}
}
class B{
public int hashCode(){
return 1;
}
}
class C{
public int hashCode(){
return 2;
}
public boolean equals(Object obj){
return true;
}
}
public class HashSetTest {
public static void main(String[] args) {
HashSet books=new HashSet();
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
}
}
上面程式中向books集合中分別新增了兩個A物件、兩個B物件和兩個C物件,其中C類重寫了equals()方法總是返回true,hashCode()方法總是返回2,這將導致HashSet把兩個C物件當成同一個物件。執行上面程式看到如下結果:
[com.zhao.two.B@1, com.zhao.two.B@1, com.zhao.two.C@2, com.zhao.two.A@2a139a55, com.zhao.two.A@15db9742]
從上面程式可以看出,即使兩個A物件通過equals()方法比較返回true,但HashSet依然把它們當成;兩個物件;即使兩個B物件的hashCode()返回相同值都是1,但HashSet依然把它們當成兩個物件。
這裡有一個注意點:當把一個物件放入HashSet中時,如果需要寫該物件對應類的equals()方法,則也應該重寫其hashCode()方法。規則是:如果兩個物件通過equals()方法比較返回true,這兩個物件的hashCode值也應該相同。
如果需要把某個類的物件儲存到HashSet集合中,重寫這個類的equals()方法和hashCode()方法時,應該儘量保證兩個物件通過equals()方法比較返回true,他們的hashCode()方法返回值也相等。
相關文章
- 轉:Java中的HashSet, TreeSet, HashMap, TreeMapJavaHashMap
- Java程式設計中的HashSet和BitSetJava程式設計
- Java集合系列-HashSetJava
- Java原始碼系列 -- HashSetJava原始碼
- Java集合 HashSet的原理及常用方法Java
- Java HashMap 和 HashSet 的高效使用技巧JavaHashMap
- Java中實現執行緒安全HashSet的幾種方法 | baeldungJava執行緒
- HashTable HashMap HashSet區別(java)HashMapJava
- Java集合原始碼分析(九)——HashSetJava原始碼
- Java集合(5)一 HashMap與HashSetJavaHashMap
- Java中Collection Frame中常用集合簡析(ArrayList,Vector,HashSet,TreeSet...)Java
- Java集合原始碼學習(4)HashSetJava原始碼
- Java Set 常用集合 HashSet、LinkedHashSet、TreeSetJava
- 結合實戰和原始碼來聊聊Java中的SPI機制?原始碼Java
- 結合 TreeMap 原始碼分析紅黑樹在 java 中的實現原始碼Java
- JAVA與groovy指令碼的結合使用Java指令碼
- HashSet
- Java中的繼承與組合Java繼承
- Java集合框架原始碼剖析:HashSet 和 HashMapJava框架原始碼HashMap
- Java 集合框架 HashSet 和 HashMap 原始碼剖析Java框架HashMap原始碼
- HashSet中重寫haseCode和equals
- java Stream結合函式方法Java函式
- dockerfile中ENTRYPOINT與CMD的結合Docker
- Java中的合併排序演算法Java排序演算法
- Java容器類框架分析(5)HashSet原始碼分析Java框架原始碼
- Java類集框架 —— HashSet、LinkedHashSet原始碼分析Java框架原始碼
- java基礎:HashSet/LinkedHashSet/TreeSet — 原始碼分析Java原始碼
- HashSet的特性介紹
- MongoDB中複合索引結構MongoDB索引
- Java鎖的邏輯(結合物件頭和ObjectMonitor)Java物件Object
- java中的HashMap用法總結JavaHashMap
- jdk-HashSetJDK
- HashSet和HashMapHashMap
- HashSet與HashMap的區別HashMap
- Go和JavaScript結合使用:抓取網頁中的影像連結GoJavaScript網頁
- MSE 結合 Dragonwell,讓 Java Agent 更好用GoJava
- 深入理解java中的組合和繼承Java繼承
- Java中的String不再糾結Java