1.两个list如果有重复元素(如List1: a,b,a List2: b,b,a) 是无法通过包含关系来判断是否相等的.
有两个办法,其一是两个List排序后再按顺序比较.另一个办法就是计算各元素的重复项再进行比较
第一种方案劣势太明显,时间复杂度过大
第二种以空间换时间,只需要遍历无需排序即可.
1/// <summary> 2 /// 判断两个集合是否是相等的(所有的元素及数量都相等) 3 /// </summary> 4 /// <typeparam name="T">集合元素类型</typeparam> 5 /// <param name="sourceCollection">源集合列表</param> 6 /// <param name="targetCollection">目标集合列表</param> 7 /// <returns>两个集合相等则返回True,否则返回False</returns> 8 public static bool EqualList<T>(this IList<T> sourceCollection, IList<T> targetCollection) where T : IEquatable<T> 9 { 10 //空集合直接返回False,即使是两个都是空集合,也返回False 11 if (sourceCollection == null || targetCollection == null) 12 { 13 return false; 14 } 15 16 if (object.ReferenceEquals(sourceCollection, targetCollection)) 17 { 18 return true; 19 } 20 21 if (sourceCollection.Count != targetCollection.Count) 22 { 23 return false; 24 } 25 26 var sourceCollectionStaticsDict = sourceCollection.StatisticRepetition(); 27 var targetCollectionStaticsDict = targetCollection.StatisticRepetition(); 28 29 return sourceCollectionStaticsDict.EqualDictionary(targetCollectionStaticsDict); 30 } 31 32 /// <summary> 33 /// 判断两个字典是否是相等的(所有的字典项对应的值都相等) 34 /// </summary> 35 /// <typeparam name="TKey">字典项类型</typeparam> 36 /// <typeparam name="TValue">字典值类型</typeparam> 37 /// <param name="sourceDictionary">源字典</param> 38 /// <param name="targetDictionary">目标字典</param> 39 /// <returns>两个字典相等则返回True,否则返回False</returns> 40 public static bool EqualDictionary<TKey, TValue>(this Dictionary<TKey, TValue> sourceDictionary, Dictionary<TKey, TValue> targetDictionary) 41 where TKey : IEquatable<TKey> 42 where TValue : IEquatable<TValue> 43 { 44 //空字典直接返回False,即使是两个都是空字典,也返回False 45 if (sourceDictionary == null || targetDictionary == null) 46 { 47 return false; 48 } 49 50 if (object.ReferenceEquals(sourceDictionary, targetDictionary)) 51 { 52 return true; 53 } 54 55 if (sourceDictionary.Count != targetDictionary.Count) 56 { 57 return false; 58 } 59 60 //比较两个字典的Key与Value 61 foreach (var item in sourceDictionary) 62 { 63 //如果目标字典不包含源字典任意一项,则不相等 64 if (!targetDictionary.ContainsKey(item.Key)) 65 { 66 return false; 67 } 68 69 //如果同一个字典项的值不相等,则不相等 70 if (!targetDictionary[item.Key].Equals(item.Value)) 71 { 72 return false; 73 } 74 } 75 76 return true; 77 } 78 79 /// <summary> 80 /// 统计集合的重复项,并返回一个字典 81 /// </summary> 82 /// <typeparam name="T">集合元素类型</typeparam> 83 /// <param name="sourceCollection">统计集合列表</param> 84 /// <returns>返回一个集合元素及重复数量的字典</returns> 85 private static Dictionary<T, int> StatisticRepetition<T>(this IEnumerable<T> sourceCollection) where T : IEquatable<T> 86 { 87 var collectionStaticsDict = new Dictionary<T, int>(); 88 foreach (var item in sourceCollection) 89 { 90 if (collectionStaticsDict.ContainsKey(item)) 91 { 92 collectionStaticsDict[item]++; 93 } 94 else 95 { 96 collectionStaticsDict.Add(item, 1); 97 } 98 } 99 100 return collectionStaticsDict; 101 }
2
1public class CommonTest 2 { 3 /// <summary> 4 /// 集合相等比较 5 /// </summary> 6 [Fact] 7 public void ListEqual_Tests() 8 { 9 var sourceList = new List<string>() 10 { 11 "a", 12 "b", 13 "a" 14 }; 15 16 var targetList = new List<string>() 17 { 18 "b", 19 "b", 20 "a" 21 }; 22 23 var resp = sourceList.EqualList(targetList); 24 Assert.False(resp ); 25 } 26 27 /// <summary> 28 /// 集合相等比较 29 /// </summary> 30 [Fact] 31 public void ListEqual2_Tests() 32 { 33 var sourceList = new List<string>() 34 { 35 "a", 36 "b", 37 }; 38 39 var targetList = new List<string>() 40 { 41 "b", 42 "a" 43 }; 44 45 var resp = sourceList.EqualList(targetList); 46 Assert.True(resp); 47 } 48 }