1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        List 去重的 6 種方法,這個方法最完美!

        共 5908字,需瀏覽 12分鐘

         ·

        2021-12-11 08:58

        作者 | 王磊

        來源 | Java中文社群(ID:javacn666)

        轉載請聯(lián)系授權(微信ID:GG_Stone)

        在日常的業(yè)務開發(fā)中,偶爾會遇到需要將 List 集合中的重復數(shù)據(jù)去除掉的場景。

        這個時候可能有同學會問:為什么不直接使用 Set 或者 LinkedHashSet 呢?這樣不就沒有重復數(shù)據(jù)的問題了嘛?

        不得不說,能提這個問題的同學很機智,一眼就看到了問題的本質(zhì)。

        但是,在實際的業(yè)務開發(fā)中遇到的情況會更復雜。比如,List 集合可能是歷史遺留問題,也有可能是調(diào)用接口返回的類型限制,只能使用 List 接收,又或者是代碼寫了一半,在做多個集合合并的時候才發(fā)現(xiàn)了這個問題,總之造成問題的原因有很多種,這里就不一一列舉了。

        當發(fā)現(xiàn)這個問題之后,如果可以通過改造原有代碼,把原來的 List 類型替換成 Set 類型,那就可以直接修改集合的類型即可。但如果壓根就修改不了,或者是修改的成本太大,那接下來這 6 種去重的方法,將幫你將解決問題。

        前置知識

        正式開始之前,先來搞懂兩組概念:無序集合和有序集合 & 無序和有序。因為接下來的方法實現(xiàn)中,會反復提及這兩組概念,所以有必要在正式開始之前,先把它們搞清楚。

        無序集合

        無序集合是指,數(shù)據(jù)讀取的順序和數(shù)據(jù)插入的順序是不一致的。

        例如,插入集合的順序是:1、5、3、7,而集合的讀取順序竟然是:1、3、5、7。

        有序集合

        有序集合的概念和無序集合的概念正好相反,它是指集合的讀取順序和插入順序是一致的。

        例如,插入數(shù)據(jù)的順序是:1、5、3、7,那么讀取的順序也是:1、5、3、7。

        有序和無序

        通過上面的無序集合和有序集合,我們可以得出有序和無序的概念。有序指的是數(shù)據(jù)的排列順序和讀取順序符合我們的預期就叫做有序。而無序指的是數(shù)據(jù)的排列順序和讀取順序不符合我們的預期就叫做無序。

        PS:如果對于有序和無序的概念不是很清楚也沒關系,通過下面的事例,我們可以進一步的理解它們的含義。

        方法1:contains判斷去重(有序)

        要進行數(shù)據(jù)去重,我們首先想到的是新建一個集合,然后循環(huán)原來的集合,每次循環(huán)判斷原集合中的循環(huán)項,如果當前循環(huán)的數(shù)據(jù),沒有在新集合中存在就插入,已經(jīng)存在了就舍棄,這樣當循環(huán)執(zhí)行完,我們就得到了一個沒有重復元素的集合了,實現(xiàn)代碼如下:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method(list);
        ????}

        ????/**
        ?????*?自定義去重
        ?????*?@param?list
        ?????*/

        ????public?static?void?method(List?list)?{
        ????????//?新集合
        ????????List?newList?=?new?ArrayList<>(list.size());
        ????????list.forEach(i?->?{
        ????????????if?(!newList.contains(i))?{?//?如果新集合中不存在則插入
        ????????????????newList.add(i);
        ????????????}
        ????????});
        ????????System.out.println("去重集合:"?+?newList);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:此方法的優(yōu)點的:理解起來比較簡單,并且最終得到的集合也是有序的,這里的有序指的是新集合的排列順序和原集合的順序是一致的;但缺點是實現(xiàn)代碼有點多,不夠簡潔優(yōu)雅。

        方法2:迭代器去重(無序)

        自定義 List 去重,除了上面的新建集合之外,我們也可以使用迭代器循環(huán)判斷每一項數(shù)據(jù),如果當前循環(huán)的數(shù)據(jù),在集合中存在兩份或兩份以上,就將當前的元素刪除掉,這樣循環(huán)完之后,也可以得到一個沒有重復數(shù)據(jù)的集合,實現(xiàn)代碼如下:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method_1(list);
        ????}

        ????/**
        ?????*?使用迭代器去重
        ?????*?@param?list
        ?????*/

        ????public?static?void?method_1(List?list)?{
        ????????Iterator?iterator?=?list.iterator();
        ????????while?(iterator.hasNext())?{
        ????????????//?獲取循環(huán)的值
        ????????????Integer?item?=?iterator.next();
        ????????????//?如果存在兩個相同的值
        ????????????if?(list.indexOf(item)?!=?list.lastIndexOf(item))?{
        ????????????????//?移除最后那個相同的值
        ????????????????iterator.remove();
        ????????????}
        ????????}
        ????????System.out.println("去重集合:"?+?list);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:此方法的實現(xiàn)比上一種方法的實現(xiàn)代碼要少一些,并且不需要新建集合,但此方法得到的新集合是無序的,也就是新集合的排列順序和原集合不一致,因此也不是最優(yōu)的解決方案。

        方法3:HashSet去重(無序)

        我們知道 HashSet 天生具備“去重”的特性,那我們只需要將 List 集合轉換成 HashSet 集合就可以了,實現(xiàn)代碼如下:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method_2(list);
        ????}

        ????/**
        ?????*?使用?HashSet?去重
        ?????*?@param?list
        ?????*/

        ????public?static?void?method_2(List?list)?{
        ????????HashSet?set?=?new?HashSet<>(list);
        ????????System.out.println("去重集合:"?+?set);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:此方法的實現(xiàn)代碼較為簡潔,但缺點是 HashSet 會自動排序,這樣新集合的數(shù)據(jù)排序就和原集合不一致了,如果對集合的順序有要求,那么此方法也不能滿足當前需求。

        方法4:LinkedHashSet去重(有序)

        既然 HashSet 會自動排序不能滿足需求,那就使用 LinkedHashSet,它既能去重又能保證集合的順序,實現(xiàn)代碼如下:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method_3(list);
        ????}

        ????/**
        ?????*?使用?LinkedHashSet?去重
        ?????*?@param?list
        ?????*/

        ????public?static?void?method_3(List?list)?{
        ????????LinkedHashSet?set?=?new?LinkedHashSet<>(list);
        ????????System.out.println("去重集合:"?+?set);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:從上述代碼和執(zhí)行結果可以看出,LinkedHashSet 是到目前為止,實現(xiàn)比較簡單,且最終生成的新集合與原集合順序保持一致的實現(xiàn)方法,是我們可以考慮使用的一種去重方法。

        方法5:TreeSet去重(無序)

        除了以上的 Set 集合之外,我們還可以使用 TreeSet 集合來實現(xiàn)去重功能,實現(xiàn)代碼如下:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method_4(list);
        ????}

        ????/**
        ?????*?使用?TreeSet?去重(無序)
        ?????*?@param?list
        ?????*/

        ????public?static?void?method_4(List?list)?{
        ????????TreeSet?set?=?new?TreeSet<>(list);
        ????????System.out.println("去重集合:"?+?set);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:比較遺憾的是,TreeSet 雖然實現(xiàn)起來也比較簡單,但它有著和 HashSet 一樣的問題,會自動排序,因此也不能滿足我們的需求。

        方法6:Stream去重(有序)

        JDK 8 為我們帶來了一個非常實用的方法 Stream,使用它可以實現(xiàn)很多功能,比如下面的去重功能:

        public?class?ListDistinctExample?{
        ????public?static?void?main(String[]?args)?{
        ????????List?list?=?new?ArrayList()?{{
        ????????????add(1);
        ????????????add(3);
        ????????????add(5);
        ????????????add(2);
        ????????????add(1);
        ????????????add(3);
        ????????????add(7);
        ????????????add(2);
        ????????}};
        ????????System.out.println("原集合:"?+?list);
        ????????method_5(list);
        ????}

        ????/**
        ?????*?使用?Stream?去重
        ?????*?@param?list
        ?????*/

        ????public?static?void?method_5(List?list)?{
        ????????list?=?list.stream().distinct().collect(Collectors.toList());
        ????????System.out.println("去重集合:"?+?list);
        ????}
        }

        以上程序執(zhí)行的結果,如下所示:Stream 實現(xiàn)去重功能和其他方法不同的是,它不用新創(chuàng)建集合,使用自身接收一個去重的結果就可以了,并且實現(xiàn)代碼也很簡潔,并且去重后的集合順序也和原集合的順序保持一致,是我們最優(yōu)先考慮的去重方法。

        總結

        本文我們介紹了?6?種集合去重的方法,其中實現(xiàn)最簡潔,且去重之后的順序能和原集合保持一致的實現(xiàn)方法,只有兩種:LinkedHashSet?去重和?Stream?去重,而后一種去重方法無需借助新集合,是我們優(yōu)先考慮的去重方法。


        往期推薦

        Java 中 List 分片的 5 種方法!


        數(shù)組轉List的3種方法和使用對比!


        優(yōu)雅統(tǒng)計代碼耗時的4種方法!


        瀏覽 62
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            久艹人人艹视频 | 亚洲精品乱码久久久久蜜桃网站 | 国内自拍偷拍视频 | 小男生露j撒尿 | 小俊灬轻点灬太深了更新时间 | 就去干成人网 | 欧美在线网址 | 成人毛片18女人毛片免费按摩店 | 成人免费看片 视频 | 午夜视频在线观看入口 |