• 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
  • 相关阅读:
    【斜率DP】BZOJ 1010:玩具装箱
    【string】KMP, 扩展KMP,trie,SA,ACAM,SAM,最小表示法
    网络流24题 (一)
    关于ax+by=c的解x,y的min(|x|+|y|)值问题
    【概率】COGS 1487:麻球繁衍
    【概率】poj 2096:Collecting Bugs
    [洛谷P5376] 过河卒二
    [TJOI2019] 洛谷P5339 唱、跳、rap和篮球
    [洛谷P3851] TJOI2007 脱险
    [洛谷P3843] TJOI2007 迷路
  • 原文地址:https://www.cnblogs.com/lgjava/p/12309764.html
Copyright © 2020-2023  润新知