完全复制https://www.cnblogs.com/czpblog/archive/2012/08/06/2625794.html
先上测试结果
代码
1 package com.syl.test; 2 3 import java.util.*; 4 5 /** 6 * 获取两个List的不同元素(假设List自身不存在重复元素) 7 * Created by syl on 2017/12/26 0026. 8 */ 9 public class TestCompareList { 10 public static void main(String[] args) { 11 List<String> list1 = new ArrayList<String>(); 12 List<String> list2 = new ArrayList<String>(); 13 for (int i = 0; i < 30000; i++) { 14 list1.add("test" + i); 15 } 16 for (int i = 0; i < 80000; i++) { 17 list2.add("test" + i * 2); 18 } 19 20 getDiffrent1(list1, list2); 21 getDiffrent2(list1, list2); 22 getDiffrent3(list1, list2); 23 getDiffrent4(list1, list2); 24 } 25 26 // 方法1,两层遍历查找,遍历次数为list1.size()*list2.size(),有点蠢 27 private static List<String> getDiffrent1(List<String> list1, List<String> list2) { 28 // diff 存放不同的元素 29 List<String> diff = new ArrayList<String>(); 30 // 开始查找的时间,用于计时 31 long start = System.currentTimeMillis(); 32 for (String str : list1) { 33 if (!list2.contains(str)) { 34 diff.add(str); 35 } 36 } 37 // 计时 38 System.out.println("方法1 耗时:" + (System.currentTimeMillis() - start) + " 毫秒"); 39 return diff; 40 } 41 42 // 方法2,两层遍历查找,用retainAll()方法查找,也很蠢,方法底层依旧是两层遍历 43 private static List<String> getDiffrent2(List<String> list1, List<String> list2) { 44 long start = System.currentTimeMillis(); 45 list1.retainAll(list2);// 返回值是boolean 46 System.out.println("方法2 耗时:" + (System.currentTimeMillis() - start) + " 毫秒"); 47 return list1; 48 } 49 50 // 方法3,用Map存放List1和List2的元素作为key,value为其在List1和List2中出现的次数 51 // 出现次数为1的即为不同元素,查找次数为list1.size() + list2.size(),较方法1和2,是极大简化 52 private static List<String> getDiffrent3(List<String> list1, List<String> list2) { 53 List<String> diff = new ArrayList<String>(); 54 long start = System.currentTimeMillis(); 55 Map<String, Integer> map = new HashMap<String, Integer>(list1.size() + list2.size()); 56 // 将List1元素放入Map,计数1 57 for (String string : list1) { 58 map.put(string, 1); 59 } 60 // 遍历List2,在Map中查找List2的元素,找到则计数+1;未找到则放入map,计数1 61 for (String string : list2) { 62 Integer count = map.get(string); 63 if (count != null) { 64 map.put(string, ++count);// 此处可优化,减少put次数,即为方法4 65 continue; 66 } 67 map.put(string, 1); 68 } 69 for (Map.Entry<String, Integer> entry : map.entrySet()) { 70 if (entry.getValue() == 1) { 71 diff.add(entry.getKey()); 72 } 73 } 74 System.out.println("方法3 耗时:" + (System.currentTimeMillis() - start) + " 毫秒"); 75 return diff; 76 } 77 78 // 优化方法3,减少put次数 79 private static List<String> getDiffrent4(List<String> list1, List<String> list2) { 80 List<String> diff = new ArrayList<String>(); 81 long start = System.currentTimeMillis(); 82 Map<String, Integer> map = new HashMap<String, Integer>(list1.size() + list2.size()); 83 List<String> maxList = list1; 84 List<String> minList = list2; 85 if (list2.size() > list1.size()) { 86 maxList = list2; 87 minList = list1; 88 } 89 for (String string : maxList) { 90 map.put(string, 1); 91 } 92 for (String string : minList) { 93 Integer count = map.get(string); 94 if (count != null) { 95 map.put(string, ++count); 96 continue; 97 } 98 map.put(string, 1); 99 } 100 for (Map.Entry<String, Integer> entry : map.entrySet()) { 101 if (entry.getValue() == 1) { 102 diff.add(entry.getKey()); 103 } 104 } 105 System.out.println("方法4 耗时:" + (System.currentTimeMillis() - start) + " 毫秒"); 106 return diff; 107 108 } 109 110 }