C#:HashSet<T> 去重

HashSet<T> 底层基于哈希表实现,去重依赖 `GetHashCode()` 和 `Equals()` 两个方法。添加元素时,先计算哈希码定位桶位置,若哈希冲突则调用 `Equals()` 比较内容。若两者均判定相等,则视为重复元素不予添加。

关键机制:

  1. 哈希分流:通过 `GetHashCode()` 快速定位存储桶,平均时间复杂度 O(1)。

  2. 精确比对:哈希值相同(冲突)时,才执行 `Equals()` 进行逐字段比较。

  3. 契约约束:若 `Equals()` 返回 true,`GetHashCode()` 必须返回相同值;反之不成立。

常见陷阱与修复:

* 引用类型默认行为:未重写上述两方法时,默认比较内存地址,导致内容相同的不同对象被视为不重复。

* 性能优化:`Add()` 返回 bool 值,直接利用返回值判断是否为新元素,避免额外调用 `Contains()` 造成二次哈希查找。

using System;

using System.Collections.Generic;

// 方案1:使用 record (C9+),编译器自动生成正确的 GetHashCode 和 Equals

public record Person(string Name, int Age);

// 方案2:传统 class 需手动重写

public class Product

{

public string Id { get; set; }

public string Name { get; set; }

public override bool Equals(object obj)

{

if (obj is Product other)

return Id == other.Id; // 根据业务主键判断

return false;

}

public override int GetHashCode()

{

return HashCode.Combine(Id); // 确保参与 Equals 的字段也参与哈希计算

}

}

class Program

{

static void Main()

{

// 1. 基础类型去重 (int/string 已内置正确实现)

var numbers = new List<int> { 1, 2, 2, 3, 4, 4, 5 };

var uniqueNumbers = new HashSet<int>(numbers); // 构造函数直接去重

Console.WriteLine($"Unique Numbers: {string.Join(", ", uniqueNumbers)}");

// 2. 复杂对象去重 (使用 record)

var people = new List<Person>

{

new Person("Alice", 25),

new Person("Bob", 30),

new Person("Alice", 25) // 重复

};

var uniquePeople = new HashSet<Person>(people);

// 3. 流式处理去重 (利用 Add 返回值,避免二次查找)

var rawIds = new List<string> { "A01", "A02", "A01", "A03" };

var seenIds = new HashSet<string>();

foreach (var id in rawIds)

{

if (seenIds.Add(id)) // Add 返回 true 表示是新元素,false 表示已存在

{

Console.WriteLine($"Processing new ID: {id}");

}

}

}

}

```

相关推荐
胖纸不争4 小时前
嫌桌面 Agent 太重,我“自己”写了一个
ai·c#·net core
当青春邂逅吉米多维奇8 小时前
C#图解教程(第5版) 同步方法
开发语言·c#
波力海苔夹心脆6758 小时前
C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解
开发语言·经验分享·数码相机·c#·视觉检测·.net
Behavior10 小时前
国内下载使用 Unity 6000 踩坑点总结
c#·unity3d·游戏开发
czhc114007566311 小时前
一张图从哪来,一个判断往哪走
c#
曹牧21 小时前
C#:未被引用的函数
c#
上位机妹子1 天前
EF Core 两种继承映射:每层次一张表(TPH)与每类型一张表(TPT)
数据库·c#·.netcore·ef core
小羊没烦恼!1 天前
jQuery1.5的改进细节
java·服务器·开发语言·前端·c#
下页、再停留1 天前
【C#桌面客户端系列学习-8】批量导出数据为csv格式
开发语言·c#·visual studio
波力海苔夹心脆6751 天前
C# 视觉检测实战:PLC 按钮触发 VisionPro 检测,OK 亮灯 / NG 灭灯(西门子 PLC,含界面显示与图片存档)
开发语言·经验分享·c#·自动化·视觉检测·.net