原文:集合去重三境界
王國維在《人間詞話》中說過治學(xué)三重境界,想要成大事者會(huì)經(jīng)歷三個(gè)階段,而數(shù)組去重幾個(gè)方式也顯示出了我們所經(jīng)歷的三個(gè)階段,你在哪個(gè)階段呢?
給定最簡單的整型集合
List list = new ArrayList<>(Arrays.asList(2,4,6,7,8,2,4,8));
第一重境界
"昨夜西風(fēng)凋碧樹,獨(dú)上高樓,望盡天涯路。"
初入猿門,人生目標(biāo)尚屬迷茫,不知前路幾何。
這個(gè)階段你應(yīng)該能想到的就是 使用一個(gè)新的List,將原來的內(nèi)容存入其中,如果存在了就跳過,這樣最后新的List中就沒有重復(fù)的元素了。
List newList = new ArrayList<>();
for(int i=0; i<list.size(); i++){
if (!newList.contains(list.get(i))){
newList.add(list.get(i));
}
}
此種方法的時(shí)間復(fù)雜度為 O(n^2) , 時(shí)間隨著集合長度的增加而指數(shù)增加。
第二重境界
"衣帶漸寬終不悔,為伊消得人憔悴。"
此刻你應(yīng)該有了追逐的目標(biāo),coding雖虐你千百遍,但你仍不悔不棄。
當(dāng)你學(xué)習(xí)了更多集合框架,你會(huì)發(fā)現(xiàn)一個(gè)Set接口,它的實(shí)現(xiàn)類要求包含的元素不能重復(fù)。
Set set = new HashSet(list);
List integers = new ArrayList<Integer>(set);
此種方法的時(shí)間復(fù)雜度為 O(n) , 時(shí)間隨著集合長度的增加而線性增加。
第三重境界
"眾里尋他千百度,驀然回首,那人卻在,燈火闌珊處。"
歷經(jīng)千百次的磨煉尋覓,突然柳暗花明,這就是升華。
如果你再進(jìn)一步學(xué)習(xí),對(duì)JDK8有些了解,那么你一定知道stream,它常用于對(duì)集合的操作,提供了非常豐富的API。
list.parallelStream()
.distinct()
.collect(Collectors.toList());
此種方式是比較流行的方式,時(shí)間復(fù)雜度我也不知怎么算了(手動(dòng)捂臉),但利用lambda表達(dá)式書寫起來行云流水,讓人直叫爽。
但它的效率如何呢?
這個(gè)要了解一下stream的實(shí)現(xiàn)方式了,它底層使用了JDK7提供的forkjoin框架來完成,這個(gè)框架能夠充分利用計(jì)算機(jī)的多核。
在多核心的計(jì)算機(jī)且數(shù)據(jù)量較大的情況下,效率相對(duì)for循環(huán)要好很多,但仍然趕不上set方式;
在數(shù)據(jù)量較小的情況下,stream相對(duì)于前面兩種方式較差。
所以stream的方式和set來轉(zhuǎn)換方式,可以根據(jù)你的要求和喜好來選擇