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