C#合并2个集合的不同项

我正在寻找一种高效的方法来将第二个ICollection的不同项添加到现有的ICollection中。 我正在使用.NET 4。

这应该这样做:

list1.Union(list2).Distinct(aCustomComparer).ToList() 

只要它们是IEnumerable,你就可以使用Linq的回答:

 var union = firstCollection.Union(secondCollection); 

这将使用默认的相等比较,对于大多数对象,它是引用相等。 要更改此设置,您可以为集合中的项类型定义IEqualityComparergenerics,以执行更多语义比较,并将其指定为Union的第二个参数。

添加到现有列表的另一种方法是:

 list1.AddRange(list2.Distinct().Except(list1)); 

你问题最直接的答案 – 因为你没有详细说明你输入或需要输出的ICollection的实际类型是KeithS给出的

 var union = firstCollection.Union(secondCollection); 

这将返回一个独特的IEnumerable – 如果这是你需要的那么它非常快。 我做了一个小测试应用程序(下面),它针对重复数据删除的简单hashset方法运行union方法(MethodA)并返回一个Hashset <>(MethodB)。 联合方法DESTROYS的hashset:

方法A:1ms

方法B:2827ms

但是 – 必须将IEnumerable转换为其他类型的集合(如List <>(如发布的ADas版本))会更改所有内容:

只需将.ToList()添加到MethodA即可

 var union = firstCollection.Union(secondCollection).ToList(); 

更改结果:

方法A:3656ms

方法B:2803毫秒

所以 – 似乎需要了解您正在使用的具体案例 – 并且应该测试您提出的任何解决方案 – 因为小的(代码)更改可能会产生巨大的影响。

下面是我用来比较这些方法的测试 – 我确定这是一种愚蠢的测试方法 – 但它似乎工作:)

  private static void Main(string[] args) { ICollection collectionA = new List(); ICollection collectionB = new List(); for (int i = 0; i < 1000; i++) { string randomString = Path.GetRandomFileName(); collectionA.Add(randomString); collectionA.Add(randomString); collectionB.Add(randomString); collectionB.Add(randomString); } Stopwatch testA = new Stopwatch(); testA.Start(); MethodA(collectionA, collectionB); testA.Stop(); Stopwatch testB = new Stopwatch(); testB.Start(); MethodB(collectionA, collectionB); testB.Stop(); Console.WriteLine("MethodA: {0}ms", testA.ElapsedMilliseconds); Console.WriteLine("MethodB: {0}ms", testB.ElapsedMilliseconds); Console.ReadLine(); } private static void MethodA(ICollection collectionA, ICollection collectionB) { for (int i = 0; i < 10000; i++) { var result = collectionA.Union(collectionB); } } private static void MethodB(ICollection collectionA, ICollection collectionB) { for (int i = 0; i < 10000; i++) { var result = new HashSet(collectionA); foreach (string s in collectionB) { result.Add(s); } } }