文章一开始,我们来看看下面这个简单的实例。

代码片段1:

int[] ints1 = { 2, 4, 9, 3, 0, 5, 1, 7 };
int[] ints2 = { 1, 3, 6, 4, 4, 9, 5, 0 };
IEnumerable<int> intsUnion = ints1.Union(ints2);
IEnumerable<int> intsContact = ints1.Concat(ints2); Console.WriteLine("数组ints1:");
foreach (int num in ints1)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
Console.WriteLine("数组ints2:");
foreach (int num in ints2)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
Console.WriteLine("Union后的结果:");
foreach (int num in intsUnion)
{
Console.Write("{0} ", num);
}
Console.WriteLine();
Console.WriteLine("Concat后的结果:");
foreach (int num in intsContact)
{
Console.Write("{0} ", num);
}

运行结果:

从结果可以看出,Union与Contact方法都是计算两个集合的并集,只是,Union方法的返回结果中,重复元素仅保留一个(与数学中的集合并集操作一致)。

接着看下面这个例子。

代码片段2:

class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Class { get; set; }
public int Score { get; set; }
} List<Student> stuList1 = new List<Student>()
{
new Student(){Id=1,Name="tiana0",Class="04机制春",Score=100},
new Student(){Id=2,Name="xiaobo",Class="09计研",Score=80},
new Student(){Id=3,Name="八戒",Class="09计研",Score=30}
}; List<Student> stuList2 = new List<Student>()
{
new Student(){Id=1,Name="tiana0",Class="04机制春",Score=100},
new Student(){Id=2,Name="张三",Class="09计研",Score=100},
new Student(){Id=1,Name="八戒",Class="09计研",Score=30}
}; IEnumerable<Student> unionList = stuList1.Union(stuList2);
IEnumerable<Student> concatList = stuList1.Concat(stuList2);
Console.WriteLine("stuList1:Id,Name,Class,Score");
foreach (var s1 in stuList1)
{
Console.WriteLine("{0},{1},{2},{3}", s1.Id, s1.Name, s1.Class, s1.Score);
}
Console.WriteLine("stuList2:Id,Name,Class,Score");
foreach (var s2 in stuList2)
{
Console.WriteLine("{0},{1},{2},{3}", s2.Id, s2.Name, s2.Class, s2.Score);
}
Console.WriteLine("unionList:Id,Name,Class,Score");
foreach (var s3 in unionList)
{
Console.WriteLine("{0},{1},{2},{3}", s3.Id, s3.Name, s3.Class, s3.Score);
}
Console.WriteLine("concatList:Id,Name,Class,Score");
foreach (var s4 in concatList)
{
Console.WriteLine("{0},{1},{2},{3}", s4.Id, s4.Name, s4.Class, s4.Score);
}

运行结果:

查看结果,发现,Union与Contact方法返回结果完全相同,也就是说,Union方法并没有对重复元素进行“去重”(去掉多余的,保留一个)处理。

那到底是哪里出了问题呢?

翻阅msdn了解到,Union方法之所以能进行“去重”操作,是因为Union方法通过使用默认的相等比较器生成两个序列的并集。 也就是说Union方法中会使用默认的相等比较器对元素进行判断,若相等,则进行“去重”操作。

另外,还了解到,如果希望比较自定义数据类型的对象的序列,则必须在类中实现 IEqualityComparer<T>泛型接口。

到这里,再次改造自己的代码。

代码片段3:

class Student : IEquatable<Student>
{
public int Id { get; set; }
public string Name { get; set; }
public string Class { get; set; }
public int Score { get; set; } public bool Equals(Student other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false; //Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true; //Check whether the Students' properties are equal.
return Id.Equals(other.Id) && Name.Equals(other.Name) && Class.Equals(other.Class) && Score.Equals(other.Score);
} // If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the Id field.
int hashStudentId = Id.GetHashCode(); //Get hash code for the Name field if it is not null.
int hashStudentName = Name == null ? 0 : Name.GetHashCode(); //Get hash code for the Class field if it is not null.
int hashStudentClass = Class == null ? 0 : Class.GetHashCode(); //Get hash code for the Score field.
int hashStudentScore = Score.GetHashCode(); //Calculate the hash code for the Student.
return hashStudentId ^ hashStudentName ^ hashStudentClass ^ hashStudentScore;
}
}

代码片段3仅修改了Student代码,使其 实现 IEqualityComparer<T>泛型接口。

这里有个小疑问,明明说的是实现IEqualityComparer<T>泛型接口,为什么Student必须实现IEquatable<Student>接口,大家知道吗?望指教。由于时间关系,这里就不再研究了,下次等我研究清楚后再专门叙述。

再次运行程序,得到以下结果:

Union方法又能正常“去重”了。

Linq中Union与Contact方法用法对比的更多相关文章

  1. Linq中关键字的作用及用法

    Linq中关键字的作用及用法 1.All:确定序列中的所有元素是否都满足条件.如果源序列中的每个元素都通过指定谓词中的测试,或者序列为空,则为 true:否则为 false. Demo: 此示例使用 ...

  2. 转载有个小孩跟我说LINQ(重点讲述Linq中GroupBy的原理及用法)

    转载原出处: http://www.cnblogs.com/AaronYang/archive/2013/04/02/2994635.html 小孩LINQ系列导航:(一)(二)(三)(四)(五)(六 ...

  3. oracle中union和minus的用法【oracle技术】

    UNION是将两个或者两个以上的搜索结果集合并在一起!这个合并是有条件滴!记录的类型要匹配啦,记录的列数要一样啦!看看下面简单的例子: 有的朋友会说为什么要用union呢,直接用txt3 in ('I ...

  4. LINQ中in的实现方法-LINQ To Entities如何实现查询 select * from tableA where id in (1,2,3,4)

    如果用in是字符串类型无问题,可以直接这样用 ).Where(entity => urls.Contains((entity.NavigateUrl == null ? "" ...

  5. javascript中call,apply,bind的用法对比分析

    这篇文章主要给大家对比分析了javascript中call,apply,bind三个函数的用法,非常的详细,这里推荐给小伙伴们.   关于call,apply,bind这三个函数的用法,是学习java ...

  6. Linq中DeferredLoadingEnabled,DataLoadOption的用法

    1.  基本的数据关系图 Student和Class之间是多对一关系,Student和Course之间是多对多关系. DataContext的DeferredLoadingEnabled属性指定是否需 ...

  7. MySql语句中Union和join的用法

    Union UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时,每条 SELECT ...

  8. C++中union的使用方法

    转载:https://blog.csdn.net/hou09tian/article/details/80816445 1 概述 1.1 定义 union即为联合,它是一种特殊的类.通过关键字unio ...

  9. 关于SQL中Union和Join的用法

    转自帘卷西风的专栏(http://blog.csdn.net/ljxfblog) https://blog.csdn.net/ljxfblog/article/details/52066006 Uni ...

随机推荐

  1. 那些年优秀的HTML5活动页面

    一个好的手机活动宣传 更能让人分享 传播是爆炸性的 下面是我平时看到一些好的微信活动宣传页面  分享给大家 其中用到的技术 常做微信活动 专题页面的人 可以看看大神们是怎么做的  这样到自己做的时候 ...

  2. 获取网络图片的大小 改变 图片色值 灰度什么的方法集合-b

    直接上代码了 头文件 // 图片处理 0 半灰色  1 灰度   2 深棕色    3 反色 +(UIImage*)imageWithImage:(UIImage*)image grayLevelTy ...

  3. BZOJ 4008 亚瑟王

    Description 小K不慎被LL邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑. 他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个看脸的游 ...

  4. 基于MVC模式的数据库综合练习

    一.准备 没什么好说的,直接上代码.... 下面是web.xml <servlet> <servlet-name>list_user</servlet-name> ...

  5. Lunch Time

    hdu4807:http://acm.hdu.edu.cn/showproblem.php?pid=4807 题意:给你n个点(0--n-1),点之间是有向边,0号点有k个人,现在0号点的k个人要到n ...

  6. 用JQUERY的deferred异步按顺序调用后端API

    花了两天啊,想办法. 顺便,DJANGO分页的东东也熟悉了下. 如果不用最新的deferred这个东东,那我们以前传统的链式异步调用代码很难看,且长. 以下这个东东未作优化代码封装. this的参数用 ...

  7. android 自定义命名空间

    一.统一的用户界面是可以使得应用程序更友好.要做到用户界面的统一,我们就必须用到风格(style)和主题(theme).自定义一个View的方法步骤如下:1.首先,在values文件夹下定义一个att ...

  8. WPF 界面布局DockPanel stackPanel WrapPanel 元素内容以及位置控制

    1 DockPanel 1) 默认充满整个窗口. 2) 最后一个出现的部分,默认充满剩余空间. 3) 非最后一个出现的部分,根据其中内容,进行分配空间s 2 StackPanel 实现居左,居右,居中 ...

  9. Android中moveTo、lineTo、quadTo、cubicTo、arcTo详解(实例)

    1.Why 最近在写android画图经常用到这几个什么什么To,一开始还真不知道cubicTo这个方法,更不用说能不能分清楚它们了,所以特此来做个小笔记,记录下moveTo.lineTo.quadT ...

  10. CSS3 :nth-of-type() 选择器

    可以设定第几个元素的样式 案例 css .qrcode img { margin-top: 30px; } .qrcode p:nth-of-type(1) { /*第一个p*/ font-size: ...