Java如何判斷兩個集合的元素是否完全相等


一,實現

1. 最簡單粗暴的方法,遍歷循環

 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent(list, list1));
19     }
20     
21     /**
22      * 方法一:使用循環遍歷
23      */
24      private static boolean checkDiffrent(List<String> list, List<String> list1) {
25         long st = System.nanoTime();
26         if(list.size() != list1.size()) {
27             System.out.println("消耗時間:" + (System.nanoTime() - st));
28             return false;
29         }
30         for(String str : list) {
31             if(!list1.contains(str)) {
32                 System.out.println("消耗時間:" + (System.nanoTime() - st));
33                 return false;
34             }
35         }
36         System.out.println("消耗時間:" + (System.nanoTime() - st));
37         return true;
38      }
39  }

返回結果為:

消耗時間為: 16657988
false

2. 使用List的retainAll方法進行比較

 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent1(list, list1));
19     }
20     
21     /**
22      * 方法2:利用List的 retainAll的方法進行判斷
23      */
24     private static boolean checkDiffrent1(List<String> list, List<String> list1) {
25         long st = System.nanoTime();
26         System.out.println("消耗時間為:" + (System.nanoTime() - st));
27         return !list.retainAll(list1);
28     }
29     
30 }

返回結果為:

消耗時間為:7711
false

但是這個retainAll這個方法有缺陷,如果集合A數組的大小沒有改變,則返回false。如果集合A和集合B是完全相同的集合,也會返回false。兩個集合沒有交集,才會返回true。簡單來說,判斷兩個集合是否有交集,有則返回false,無則返回true(這句話不嚴謹)。總結來說只有兩個任何一個元素都不相等時才會返回true,否則返回false。

3. 利用HashMap的唯一性,把元素當做key,value可以重復。把list存到HashMap中
    我們的需求是判斷兩個List中的元素是否相同,那么可以這樣考慮:用一個map存放list的所有元素,其中的key為list1的各個元素,value為該元素出現的次數,接着把list2的所有元素也放到map里,如果已經存在則value+1,一旦value停止+1,說明有元素不同了,返回false。否則一直遍歷直至list2中所有元素,返回true。這樣我們只需循環m+n次,大大減少了循環的次數。

 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent1(list, list1));
19     }
20     
21      /** 
22       * 方法3 
23       * 利用HashMap key唯一,value可以重復的特點,把list中各種元素放到hashMap中 
24       */
25       private static boolean checkDiffrent2(List<String> list, List<String> list1) {
26         long st = System.nanoTime();
27         Map<String, Integer> map = new HashMap<>(list.size() + list1.size());
28         if (list.size() != list1.size()) {    
29             System.out.println("消耗時間為: " + (System.nanoTime() - st));    
30             return false;
31         }
32         for (String str : list) {    
33             map.put(str, 1);
34         }
35         for (String str : list1) {    
36             Integer cc = map.get(str);    
37             if (null != cc) {        
38                 continue;    
39             }    
40             System.out.println("消耗時間為: " + (System.nanoTime() - st));    
41             return false;
42         }
43         System.out.println("消耗時間為: " + (System.nanoTime() - st));
44         return true;
45       }
46 }

結果:

消耗時間為: 4243019
false

此方法使用了HashMap中key必須唯一,但是value可以重復的原因。但是HashMap是不同步的,所以線程不安全。

4. 利用MD5加密法來判斷兩個集合是否相等

 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent1(list, list1));
19     }
20     
21      /** 
22       * md5加密法使用 
23       * 方法4 
24       */
25      private static boolean getDiffrent3(List<String> list, List<String> list1) {    
26         long st = System.nanoTime();  
27         /** 使用Security的md5方法進行加密 */
28         String str = SecureUtil.md5(list.toString());     
29         String str1 = SecureUtil.md5(list1.toString());
30         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
31         return str.equals(str1);
32     }
33 }

結果:

消耗時間為: 88603223
false

這個方法很新奇吧,是我沒有想到的,最好不要用這種方法,如果你在實際項目中使用這種方法,被打死了,請不要找我emmm~

5. 使用Java8的新特性steam流去比較兩個數組是否相等
 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent4(list, list1));
19     }
20     
21      /** 
22       * 使用stream流去比較兩個數組是否相等
23       * 方法5
24       */
25      private static boolean checkDiffrent4(List<String> list, List<String> list1) {    
26         long st = System.nanoTime();  
27         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
28         /** 先將集合轉成stream流進行排序然后轉成字符串進行比較 */
29         return list.stream().sorted().collect(Collectors.joining())
30                         .equals(list1.stream().sorted().collect(Collectors.joining()));
31        }
32 }

結果:

99273484
false

利用了Java8的新特性然后用collect(Collectors.joining())進行比較,雖然比較耗時,但是很好用是真的。

6. 使用list轉成字符串進行比較是否相等

 1 package list.demo;
 2 
 3 import java.io.Serializable;
 4 import java.util.*;
 5 import java.util.stream.Collectors;
 6 
 7 /**
 8  * 判斷兩個集合是否相等
 9  */
10  public class CheckDiffList implements Serializable {
11     public static void main(String[] args) {    
12         List<String> list = new ArrayList<>();    
13         List<String> list1 = new ArrayList<>();    
14         for (int i = 0; i < 1000; i++) {        
15             list.add("test" + i);        
16             list1.add("test" + (i * 2));    
17         }    
18         System.out.println(checkDiffrent4(list, list1));
19     }
20     
21      /** 
22       * 使用list自帶的sort方法先進性排序,然后轉成toString去判斷兩個集合是否相等
23       * 方法6
24       */
25      private static boolean checkDiffrent5(List<String> list, List<String> list1) { 
26         long st = System.nanoTime();
27         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
28         list.sort(Comparator.comparing(String::hashCode));  
29         list1.sort(Comparator.comparing(String::hashCode)); 
30         return list.toString().equals(list1.toString());
31     }
32 }

結果:

2570
false

個人感覺先將集合轉成字符串,然后進行equal(),進行判斷是一個比較優秀的方法, 比起用循環編輯要簡潔很多。

二,總結
    上面的六種方法的耗時時間依次是checkDiffrent5 < checkDiffrent1 < checkDiffrent2 < checkDiffrent < checkDiffrent3 < checkDiffrent4。所以最好的方法是使用list.sort()方法來進行排序,在用toString進行equal比較。
Security源代碼地址:Security地址
附下我寫的所有代碼:

  1 package list.demo;
  2 
  3 import java.io.Serializable;
  4 import java.util.*;
  5 import java.util.stream.Collectors;
  6 
  7 /**
  8  * 判斷兩個集合是否相等
  9  */
 10  public class CheckDiffList implements Serializable {
 11     public static void main(String[] args) {    
 12         List<String> list = new ArrayList<>();    
 13         List<String> list1 = new ArrayList<>();    
 14         for (int i = 0; i < 1000; i++) {        
 15             list.add("test" + i);        
 16             list1.add("test" + (i * 2));    
 17         }    
 18         System.out.println(checkDiffrent(list, list1));
 19     }
 20     
 21     /**
 22      * 方法一:使用循環遍歷
 23      */
 24      private static boolean checkDiffrent(List<String> list, List<String> list1) {
 25         long st = System.nanoTime();
 26         if(list.size() != list1.size()) {
 27             System.out.println("消耗時間:" + (System.nanoTime() - st));
 28             return false;
 29         }
 30         for(String str : list) {
 31             if(!list1.contains(str)) {
 32                 System.out.println("消耗時間:" + (System.nanoTime() - st));
 33                 return false;
 34             }
 35         }
 36         System.out.println("消耗時間:" + (System.nanoTime() - st));
 37         return true;
 38      }
 39      
 40       /**
 41      * 方法2:利用List的 retainAll的方法進行判斷
 42      */
 43     private static boolean checkDiffrent1(List<String> list, List<String> list1) {
 44         long st = System.nanoTime();
 45         System.out.println("消耗時間為:" + (System.nanoTime() - st));
 46         return !list.retainAll(list1);
 47     }
 48     
 49     /** 
 50       * 方法3 
 51       * 利用HashMap key唯一,value可以重復的特點,把list中各種元素放到hashMap中 
 52       */
 53       private static boolean checkDiffrent2(List<String> list, List<String> list1) {
 54         long st = System.nanoTime();
 55         Map<String, Integer> map = new HashMap<>(list.size() + list1.size());
 56         if (list.size() != list1.size()) {    
 57             System.out.println("消耗時間為: " + (System.nanoTime() - st));    
 58             return false;
 59         }
 60         for (String str : list) {    
 61             map.put(str, 1);
 62         }
 63         for (String str : list1) {    
 64             Integer cc = map.get(str);    
 65             if (null != cc) {        
 66                 continue;    
 67             }    
 68             System.out.println("消耗時間為: " + (System.nanoTime() - st));    
 69             return false;
 70         }
 71         System.out.println("消耗時間為: " + (System.nanoTime() - st));
 72         return true;
 73       }
 74       
 75        /** 
 76       * md5加密法使用 
 77       * 方法4 
 78       */
 79      private static boolean getDiffrent3(List<String> list, List<String> list1) {    
 80         long st = System.nanoTime();  
 81         /** 使用Security的md5方法進行加密 */
 82         String str = SecureUtil.md5(list.toString());     
 83         String str1 = SecureUtil.md5(list1.toString());
 84         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
 85         return str.equals(str1);
 86     }
 87     
 88     /** 
 89       * 使用stream流去比較兩個數組是否相等
 90       * 方法5
 91       */
 92      private static boolean checkDiffrent4(List<String> list, List<String> list1) {    
 93         long st = System.nanoTime();  
 94         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
 95         /** 先將集合轉成stream流進行排序然后轉成字符串進行比較 */
 96         return list.stream().sorted().collect(Collectors.joining())
 97                         .equals(list1.stream().sorted().collect(Collectors.joining()));
 98        }
 99        
100        /** 
101       * 使用list自帶的sort方法先進性排序,然后轉成toString去判斷兩個集合是否相等
102       * 方法6
103       */
104      private static boolean checkDiffrent5(List<String> list, List<String> list1) { 
105         long st = System.nanoTime();
106         System.out.println("消耗時間為: " + (System.nanoTime() - st)); 
107         list.sort(Comparator.comparing(String::hashCode));  
108         list1.sort(Comparator.comparing(String::hashCode)); 
109         return list.toString().equals(list1.toString());
110     }
111  }
112 
 原文鏈接:https://blog.csdn.net/Ecloss/article/details/86154344


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM