一,實現
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