HashSet的hashCode方法和equals方法的重寫,TreeSet中compareTo方法的重寫,Comparator在treeSet中的應用。code
HashSet:對象
首先,hashset底層是hash值的地址,它裏面存的對象是無序的。內存
當須要在HashSet中存入自定義對象時,就須要重寫hashset和equals方法。源碼
至於現象出現的緣由,先分析hashset存入非自定義對象的機制:hash
第一個對象進入集合時,hashset會調用object類的hashcode根據對象在堆內存裏的地址調用對象重寫的hashcode計算出一個hash值,而後第一個對象就進入hashset集合中的任意一個位置。object
第二個對象開始進入集合,hashset先根據第二個對象在堆內存的地址調用對象的計算出一個hash值,若是第二個對象和第一個對象在堆內存裏的地址是不一樣的,那麼獲得的hash值也是相同的,直接返回true,hash獲得true後就不把第二個元素加入集合(這段是hash源碼程序中的操做)。若是第二個對象和第一個對象在堆內存裏地址是不一樣的,這時hashset類會先調用本身的方法遍歷集合中的元素,當遍歷到某個元素時,調用對象的equals方法,若是相等,返回true,則說明這兩個對象的內容是相同的,hashset獲得true後不會把第二個對象加入集合。二叉樹
而後,分析爲何自定義對象加入hashset時須要重寫hashcode和equals方法:遍歷
自定義類須要先重寫object的hashcode用以獲取一個hash值,當兩個對象的內存地址相同時,直接返回true,hashset不執行加入操做。當兩個對象的內存地址不相同時,hashset會把新加入的對象與已經存在的對象逐一對比,對比時,須要調用對象的equals方法,由於自定義對象裏沒有複寫equals方法,因此須要複寫。當equals返回的是true時,代表兩個對象的內容相同,不對對象執行加入操做。這個判斷須要在自定義對象的equals方法裏來完成。程序
TreeSet:方法
首先,TreeSet的底層是經過二叉樹來完成存儲的,無序的集合。
當往treeset集合中加入自定義對象時,須要重寫compareTo方法。
先分析treeset集合對象的加入過程:
當咱們將一個對象加入treeset中,treeset會將第一個對象做爲根對象,而後調用對象的compareTo方法拿第二個對象和第一個比較,當返回至=0時,說明2個對象內容相等,treeset就不把第二個對象加入集合。返回>1時,說明第二個對象大於第一個對象,將第二個對象放在右邊,返回-1時,則將第二個對象放在左邊,依次類推,就是treeset的底層運行方式。
由於自定義對象沒有複寫compareTo方法,因此須要對象所在的類裏複寫compareTo方法,方法的定義參照上面描述的便可。
Treeset比較的是元素的天然順序,有一種狀況,當元素自己不具有比較性,或者說具有的比較性是咱們不須要的,咱們就須要一個一個比較器來定義元素比較的方式。
比較器的定義只要符合treeset執行的便可實現,即:返回的是大於0的數,就放在樹杈的右邊,等於0就不操做,小於0就放在樹杈的左邊。