问题引入:
Teacher实体的唯一标识符是Name和Classes字段(或者说这两个字段唯一确定一条数据),如何对两个实体列表做交集、差集运算呢?(并集直接调用AddRange方法即可)
一、重写方法实现
1.原理
重写 Equals() 和 GetHashCode() 方法,使用Intersect() 和 Except() 方法在比较时就会基于这些字段来判断对象是否相等
2.快速生成代码
3.代码
public class Teacher
{public int Id { get; set; }public string Name { get; set; }public string Classes { get; set; }public override bool Equals(object obj){return obj is Teacher teacher &&Name == teacher.Name &&Classes == teacher.Classes;}public override int GetHashCode(){return HashCode.Combine(Name, Classes);}
}class Program
{static void Main(){// 创建两个示例列表List<Teacher> listA = new List<Teacher>{new Teacher { Id = 1, Name = "Alice", Classes = "Math" },new Teacher { Id = 2, Name = "Bob", Classes = "Science" },new Teacher { Id = 3, Name = "Charlie", Classes = "English" }};List<Teacher> listB = new List<Teacher>{new Teacher { Id = 2, Name = "Bob", Classes = "Science" },new Teacher { Id = 3, Name = "Charlie", Classes = "English" },new Teacher { Id = 4, Name = "David", Classes = "History" }};// 求交集var intersection = listA.Intersect(listB).ToList();// 求差集 A - Bvar difference = listA.Except(listB).ToList();// 输出结果Console.WriteLine("交集:");foreach (var teacher in intersection){Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");}Console.WriteLine("\n差集 A - B:");foreach (var teacher in difference){Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");}}
}
二、嵌套查询实现
1.原理
var intersection = listA.Where(a => listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();
var difference = listA.Where(a => !listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();
where-Any相当于A表内连接B表( A ∩ B );
where-!Any相当于A表左外连接B表并剔除匹配到的数据(A - B)。
2.代码
public class Teacher
{public int Id { get; set; }public string Name { get; set; }public string Classes { get; set; }
}class Program
{static void Main(){// 创建两个示例列表List<Teacher> listA = new List<Teacher>{new Teacher { Id = 1, Name = "Alice", Classes = "Math" },new Teacher { Id = 2, Name = "Bob", Classes = "Science" },new Teacher { Id = 3, Name = "Charlie", Classes = "English" }};List<Teacher> listB = new List<Teacher>{new Teacher { Id = 2, Name = "Bob", Classes = "Science" },new Teacher { Id = 3, Name = "Charlie", Classes = "English" },new Teacher { Id = 4, Name = "David", Classes = "History" }};// 自定义方法来比较 Name 和 Classesvar intersection = listA.Where(a => listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();var difference = listA.Where(a => !listB.Any(b => b.Name == a.Name && b.Classes == a.Classes)).ToList();// 输出交集Console.WriteLine("交集:");foreach (var teacher in intersection){Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");}// 输出差集Console.WriteLine("\n差集 A - B:");foreach (var teacher in difference){Console.WriteLine($"Id: {teacher.Id}, Name: {teacher.Name}, Classes: {teacher.Classes}");}}
}