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}");

}

}

}

}

```

相关推荐
czhc11400756631 小时前
起点、口径与因果:今天用错的七把尺子
c#
c#上位机14 小时前
C#上位机项目实战——Task.Run执行带参数的方法
c#·上位机
Lost of 程序猿20 小时前
用 YARP 为 .NET 微服务搭一座“立交桥“:路由转发与生产配置实践
c#·asp.net
点纭1 天前
C 语言 第七章 常用函数(3)
c语言·开发语言·算法·oracle·c#
用户788477316341 天前
用 .NET MAUI 一套 C# 同时出 Windows 和 Android:哪些是真能共享,哪些是 marketing
c#
Lost of 程序猿1 天前
用 Quartz.NET 优雅地处理 .NET 定时任务:从选型到 Docker 部署全记录
后端·c#·asp.net
林川~011 天前
Unity 万能物理检测工具:射线检测 / 范围检测 / 层级过滤 / 编辑器可视化(可直接拿去用)
游戏·unity·c#·射线检测·通用工具
He BianGu2 天前
【WPF-VisionMaster】机器视觉通用平台V5.0版本发行说明
opencv·c#·wpf·halcon·机器视觉·visionmaster
tang_04272 天前
【Hi.Ltd 专题】第9期:Interop 配置互操作(JSON/INI/XML/YAML/注册表/扫码)
经验分享·c#·hi.ltd系列