近來在優化一些寫好的排序,因此會對數據結構考慮得更深刻,爲何面試都喜歡面試數據結構,面試對數據結構得熟悉層度,很大的狀況下是由於只有數據結構熟悉了,才能用更少時間找到優化時間和空間的方法。面試
估計不少人都有過排序的經驗,估計也不少會用到Collections裏面的一些數據結構,例如List Set 等等。安全
這一節咱們討論的是TreeSet。數據結構
TreeSet有什麼好處呢?架構
插入的同時就馬上進行排序,你只須要設定比如較器,就能按照設定來進行排序,由於他是一個紅黑樹,樹的特徵是擁有排序。同時他是個Set,只要比較器認爲是同一個,就會被去重。函數
TreeSet使用的結構組件化
其內部是使用了TreeMap,Set值保存在Map的key中,value存了一個Object,Map中若是Key值相同會被認爲是同一個,這樣就可以實現數據去重。TreeMap內部維護的是一個紅黑樹。由於是樹狀結構,那麼其查詢效率和插入效率都是log(n),固然對應耗時,會由於紅黑樹平衡調整,會有相應的耗時。性能
TreeSet不是線性安全的,線性安全須要使用ConcurrentSkipListSet。內部是SkipList(跳錶)結構實現,在理論上可以在O(log(n))時間內完成查找、插入、刪除操做。 優化
跳錶本質是一個鏈表,只是鏈表節點中會記錄必定跨度後的的鏈表節點地址。####屬性變動問題 TreeSet能夠指定比較器Comparator,能夠經過類中繼承Comparable來進行比較迭代。可是裏面的屬性變化了,不會從新觸發排序。須要從新插入排序。例如,TreeSet保存的類文件,類中包含一些列表,列表數據組裝而且同時插入到TreeSet,正比如較器須要比較列表中元素的屬性,這時候,由於列表是一直在變化的。會出現,類文件插入到TreeSet的時候,再變動類文件中列表的屬性,是沒法觸發TreeSet中自動排序的。TreeSet沒法判斷到其對象變動狀況。3d
你能夠採起的策略是cdn
1.插入到TreeSet前須要肯定類文件屬性再也不變動。
2.觸發變動的時候,從新將其賦值到TreeMap當中,更新比較。
####去重問題 若是比較器中返回爲0 ,Set中認爲是相等的,會執行去重操做。若是比較器邏輯有問題,可能會觸發死循環比較。
####比較器效率問題 TreeSet是邊插入邊比較,而Collections.sort函數應用場景是List隊列當中,二者都能是用比較器來完成操做。
ThreeSet的底層實現是紅黑樹,它在建立set的過程當中實現排序。Collections.sort是在對整個集合進行排序,按道理來講使用TreeSet插入集合元素直至創建整個TreeSet過程當中實現排序在時間方面要比Collections.sort對整個集合進行排序效率要高不少,由於它在每次搜索要插入的位置時耗費的時間爲log(n),n表明的是當前集合的長度,但實驗代表使用Collections.sort對集合進行排序時間耗費要少些。
出現這種狀況的緣由是
1.TreeSet的搜索時間爲log(n),明顯上是比List有優點的。
2.TreeSet在插入的時候須要先建立節點,而List比較並不須要增長額外節點。
3.TreeSet基於紅黑樹,那麼其每次插入都須要檢查和維護紅黑樹平衡,若是失衡會觸發紅黑樹結構調整。
基於2,3兩點,無疑會比List更加耗時,數據越多,效率差距越明顯。固然這裏沒有加入List的插入建立節點時間,就算將插入時間加入進來,估計效率上海市Collections.sort佔優。