查詢元素是否存在時使用List與Set與Map的比較

現在有下面這樣一個場景,


你有一個集合,而它的作用只是用來被查詢是否包含目標值,你是否也會習慣性的寫出上面這段代碼?
但是等等,看上去這段代碼用流式寫法寫的非常簡潔與流暢,但它的性能是最優選擇嗎?讓我們來到ArrayList.contains(Object o)這個方法。

可以看到,ArrayList爲我們選擇了最撈的查找方法——遍歷法
沒辦法,作爲一個最基本的List實現類,它已經做得很不錯了,那麼有沒有更好的解決辦法呢?

你好親,有的呢

 

散列



散列簡直就是爲了查找而生的,他的基本實現邏輯就是將存放的對象進行hash計算(這個計算方式可以自己實現),然後根據計算值,將對象存放到對應位置

在散列中,如果要查找一個對象是否存在應該怎麼辦呢?
沒錯,計算這個對象的hash值,然後拿出散列中對應hash值的這個對象,然後equals比較一下

這樣看,是不是比遍歷高效多了? 基本就是o(n)到o(1)的計算複雜度的提升呀

於是在代碼中,我進行了更改

衆所周知,Set是一個無序集合,裏面的值只能存在一個,而這個接口的散列實現就是HashSet,簡直完美符合我的需求!
(我還特地確認了一下是不是用的HashSet)

這一切看起來已經很棒了是嘛,是的,對於一開始的List來說,已經有了很大的性能提升了,直到我因爲好奇看了HashSet的底層實現……

???


不出所料,HashSet的add方法也是……

這個“PRESENT”是一個靜態對象。。。

所以繞了一圈,當我們遇到最初的那種情況應該怎麼辦呢?
我嘗試使用了HashMap, 發現的確可以這麼使用,

但是!

如果用的是流式寫法,並且HashMap的Value如果爲null時,會報這個問題

在運行時會報異常

如果不能傳空而要傳一個對象的話,那與HashSet的實現就沒有什麼區別了。

### 綜上所述,如果只需要看一個集合裏有沒有目標值,那麼HashSet可能是存放流式方法結果的最佳實現(也是默認實現)
如果是非流式的話,則可以直接用HashMap的put(key, null),而後使用contiansKey方法查找。當然,如果想要一個方便的散列實現,應該也不難,但是行業不通用的話,好像討論的意義也不大哦

如果有什麼比hashSet更好的無序散列集合的實現方式,請務必告訴我哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章