问题引入:
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 - B
var 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 和 Classes
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();
// 输出交集
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}");
}
}
}