自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 前端
在日常的業(yè)務(wù)開發(fā)中,偶爾會遇到需要將 List 集合中的重復(fù)數(shù)據(jù)去除掉的場景。這個時(shí)候可能有同學(xué)會問:為什么不直接使用 Set 或者 LinkedHashSet 呢?這樣不就沒有重復(fù)數(shù)據(jù)的問題了嘛?

[[438618]]

本文轉(zhuǎn)載自微信公眾號「Java中文社群」,作者磊哥 。轉(zhuǎn)載本文請聯(lián)系Java中文社群公眾號。

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

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

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

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

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

前置知識

正式開始之前,先來搞懂兩組概念:無序集合和有序集合 & 無序和有序。因?yàn)榻酉聛淼姆椒▽?shí)現(xiàn)中,會反復(fù)提及這兩組概念,所以有必要在正式開始之前,先把它們搞清楚。

無序集合

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

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

有序集合

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

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

有序和無序

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

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

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

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 自定義去重 
  19.      * @param list 
  20.      */ 
  21.     public static void method(List<Integer> list) { 
  22.         // 新集合 
  23.         List<Integer> newList = new ArrayList<>(list.size()); 
  24.         list.forEach(i -> { 
  25.             if (!newList.contains(i)) { // 如果新集合中不存在則插入 
  26.                 newList.add(i); 
  27.             } 
  28.         }); 
  29.         System.out.println("去重集合:" + newList); 
  30.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

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

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

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method_1(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 使用迭代器去重 
  19.      * @param list 
  20.      */ 
  21.     public static void method_1(List<Integer> list) { 
  22.         Iterator<Integer> iterator = list.iterator(); 
  23.         while (iterator.hasNext()) { 
  24.             // 獲取循環(huán)的值 
  25.             Integer item = iterator.next(); 
  26.             // 如果存在兩個相同的值 
  27.             if (list.indexOf(item) != list.lastIndexOf(item)) { 
  28.                 // 移除最后那個相同的值 
  29.                 iterator.remove(); 
  30.             } 
  31.         } 
  32.         System.out.println("去重集合:" + list); 
  33.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

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

方法3:HashSet去重(無序)

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method_2(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 使用 HashSet 去重 
  19.      * @param list 
  20.      */ 
  21.     public static void method_2(List<Integer> list) { 
  22.         HashSet<Integerset = new HashSet<>(list); 
  23.         System.out.println("去重集合:" + set); 
  24.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

此方法的實(shí)現(xiàn)代碼較為簡潔,但缺點(diǎn)是 HashSet 會自動排序,這樣新集合的數(shù)據(jù)排序就和原集合不一致了,如果對集合的順序有要求,那么此方法也不能滿足當(dāng)前需求。

方法4:LinkedHashSet去重(有序)

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method_3(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 使用 LinkedHashSet 去重 
  19.      * @param list 
  20.      */ 
  21.     public static void method_3(List<Integer> list) { 
  22.         LinkedHashSet<Integerset = new LinkedHashSet<>(list); 
  23.         System.out.println("去重集合:" + set); 
  24.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

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

方法5:TreeSet去重(無序)

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method_4(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 使用 TreeSet 去重(無序) 
  19.      * @param list 
  20.      */ 
  21.     public static void method_4(List<Integer> list) { 
  22.         TreeSet<Integerset = new TreeSet<>(list); 
  23.         System.out.println("去重集合:" + set); 
  24.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

比較遺憾的是,TreeSet 雖然實(shí)現(xiàn)起來也比較簡單,但它有著和 HashSet 一樣的問題,會自動排序,因此也不能滿足我們的需求。

方法6:Stream去重(有序)

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

  1. public class ListDistinctExample { 
  2.     public static void main(String[] args) { 
  3.         List<Integer> list = new ArrayList<Integer>() {{ 
  4.             add(1); 
  5.             add(3); 
  6.             add(5); 
  7.             add(2); 
  8.             add(1); 
  9.             add(3); 
  10.             add(7); 
  11.             add(2); 
  12.         }}; 
  13.         System.out.println("原集合:" + list); 
  14.         method_5(list); 
  15.     } 
  16.  
  17.     /** 
  18.      * 使用 Stream 去重 
  19.      * @param list 
  20.      */ 
  21.     public static void method_5(List<Integer> list) { 
  22.         list = list.stream().distinct().collect(Collectors.toList()); 
  23.         System.out.println("去重集合:" + list); 
  24.     } 

以上程序執(zhí)行的結(jié)果,如下所示:

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

總結(jié)

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

 

責(zé)任編輯:武曉燕 來源: Java中文社群
相關(guān)推薦

2011-02-24 10:56:34

人才

2010-10-08 11:13:22

MySQL修改密碼

2023-09-06 08:00:00

ChatGPT數(shù)據(jù)分析

2025-01-02 08:21:32

2022-06-09 08:46:58

ITCIO職業(yè)

2025-01-03 08:48:20

列表推導(dǎo)式Python編程

2022-06-10 10:25:07

CIOIT領(lǐng)導(dǎo)者職業(yè)生涯

2015-07-09 10:13:05

IT基礎(chǔ)設(shè)施支出數(shù)據(jù)中心

2023-04-26 08:41:16

Git撤消更改

2023-04-03 20:29:00

Linux環(huán)境變量

2023-05-15 18:32:20

2022-02-21 22:47:36

首席信息官IT技術(shù)

2022-05-30 16:42:20

數(shù)據(jù)中心

2022-11-08 11:00:33

2022-11-29 10:33:15

Kubectl命令pod

2024-11-05 08:28:50

2023-12-08 08:53:37

數(shù)據(jù)中心人工智能自動化

2023-11-07 11:11:42

Go性能

2023-08-02 10:05:28

2010-04-02 15:36:37

Oracle約束
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號